Hello! Welcome back to your course on the Spring Framework.
In our last lesson, we established the fundamental difference between singleton and prototype scopes. We saw that singleton beans are created once and shared, making them ideal for stateless services, while prototype beans are created anew for each request, suiting stateful components. We also ended on a critical point: injecting a prototype bean into a singleton bean doesn't give you a new prototype on each method call; the singleton caches the first instance it receives. This concept of managing beans with different lifecycles is central to today's topic.
This lesson directly addresses the learning outcome: Configure and use web-specific bean scopes (request, session) in a web application. We will move beyond the standard scopes and explore how Spring allows you to tie the lifecycle of a bean directly to the lifecycle of an HTTP request or a user's session. This is fundamental for building stateful web applications and APIs.
The Landscape of Spring Bean Scopes
So far we've covered singleton and prototype. The request and session scopes are two additional scopes available in a web context.

Defining Web-Specific Scopes
Let's start with the "what" and "why." When would you use these scopes?
- Request Scope (
@RequestScope): A new instance of the bean is created for each individual HTTP request. Once Spring sends the HTTP response, the bean instance is destroyed. This is perfect for managing state that is relevant only for the duration of a single API call. - Session Scope (
@SessionScope): A new instance is created for each unique HTTP session (e.g., a user's browser session). This single instance is shared across all requests that occur within that same session. When the session times out or is invalidated (e.g., user logs out), the bean is destroyed. This is ideal for managing state that needs to persist for a single user across multiple API calls.
To see some concrete use cases, the following resource provides clear, practical examples.
Managing Concurrency with Spring Bean Scopes: A Complete Guide
The article 'Managing Concurrency with Spring Bean Scopes' gives excellent, real-world examples for when to use request and session scopes.
Please read the sections titled 'Real-World Example' and 'Best Practices for Bean Scope Management'. Focus on the RequestAuditContext and ShoppingCart examples. They are clear illustrations of request-scoped and session-scoped beans, respectively.
As you read, consider the ShoppingCart example. It wouldn't make sense for it to be a singleton (all users would share one cart) or a request-scoped bean (the cart would be empty on every new request). Session scope is the natural fit.
The Central Challenge: Lifecycle Mismatch
Here's the problem we need to solve: In Spring, components like @RestController or @Service are singletons by default. They are created once at application startup. But how can a long-lived singleton bean use a short-lived @RequestScope bean? If the singleton's dependencies are injected only once at startup, which instance of the request-scoped bean does it get?
The answer is that it can't—at least not directly. Spring solves this problem with a powerful mechanism: scoped proxies. Instead of injecting the actual request-scoped bean, Spring injects a proxy. When you call a method on this proxy, the proxy looks up the actual bean instance for the current request and delegates the call to it.
The following video is an excellent deep dive that not only demonstrates this solution but also uses a clever trick with stack traces to let you see the proxy in action. This will connect directly with your experience in system design and debugging.
Spring Framework - Lesson 14 - Web scopes
The video 'Spring Framework - Lesson 14 - Web scopes' by Laur Spilca provides a masterful demonstration of web scopes and the underlying proxy mechanism.
Please watch from 01:56 to 35:45. This is the core of our lesson. The video covers: (01:56 - 13:55) Setting up a basic web application to demonstrate the concept. (13:55 - 29:20) Demonstrating the request scope, showing the error that occurs when injecting it into a singleton, and introducing proxyMode as the solution. (29:20 - 35:45) The most interesting part: using a stack trace to prove the existence of the Spring AOP proxy. This makes the abstract concept of a proxy very concrete.
Understanding the Scoped Proxy Mechanism
What you just witnessed in the video is a core concept in Spring. The error "Scope 'request' is not active for the current thread" occurs because at application startup (when the singleton controller is created), there is no HTTP request. The proxy solves this by deferring access to the bean until it's actually needed within a request context.
Now, let's turn to the official documentation for a formal explanation of what you've just seen.
Bean Scopes :: Spring Framework
The official Spring documentation formally explains the 'why' and 'how' of using proxies for scoped beans.
Please read the section titled 'Scoped Beans as Dependencies'. Focus on the explanation of why a proxy is needed to inject a shorter-lived bean (like session-scoped) into a longer-lived one (like a singleton).
Choosing the Proxy Type: Class vs. Interface
The video and documentation both mention a choice in how the proxy is created. This choice is controlled by the proxyMode attribute on the @Scope annotation. Given your background in C++ and Go, the distinction between class-based and interface-based programming should be familiar.
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS): This is the default. Spring uses a library called CGLIB to create a proxy by generating a subclass of your bean at runtime. This works on concrete classes.@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES): Spring uses standard Java functionality (JDK dynamic proxies) to create a proxy that implements the same interface(s) as your bean. This requires your bean to implement an interface and for you to inject the dependency using the interface type. This approach generally aligns better with a design principle of "programming to an interface."
The next segment of the video demonstrates this difference perfectly.
Spring Framework - Lesson 14 - Web scopes
Laur Spilca now continues to explain the difference between the two proxy types.
Watch from 35:45 to 43:33. This part shows what happens when you try to use an interface-based proxy on a concrete class, and then demonstrates the correct way to do it by introducing an interface.
The Session Scope in Action
Now that you understand the proxy mechanism for request scope, the session scope works exactly the same way. The only difference is the bean's lifetime. Let's see it in action.
The key to demonstrating the session scope is to simulate two different users (i.e., two different sessions). The easiest way to do this is by using two different web browsers (or a regular and an incognito window).
Spring Framework - Lesson 14 - Web scopes
The final part of the video demonstrates the session scope.
Watch from 43:33 to 50:34. Pay close attention to how refreshing the page in the same browser returns the same value (same bean instance), while accessing it from a different browser returns a new value (new bean instance for the new session).
This confirms that the bean instance is tied to the user's session, persisting across multiple requests from that user, but remaining isolated from other users.
Conclusion
In this lesson, we explored Spring's web-specific bean scopes, which are essential tools for managing state in a web environment. We didn't just learn how to use them; we dove deep into the underlying proxy mechanism that makes them work.
Key Takeaways:
@RequestScopecreates a bean that lives for a single HTTP request, ideal for request-specific data like transaction IDs or performance monitoring.@SessionScopecreates a bean that lives for a user's entire session, perfect for stateful data like a shopping cart or user preferences.- Injecting a shorter-lived bean (
request,session) into a longer-lived bean (singleton) creates a lifecycle mismatch. - Spring resolves this by injecting a scoped proxy instead of the actual bean. This proxy delegates calls to the correct bean instance for the current request or session.
- You can control the proxy creation strategy with
proxyMode, choosing between CGLIB-based class proxies (TARGET_CLASS) or JDK-based interface proxies (INTERFACES).
We've now covered the most important aspects of Spring's core container and bean management. In the next module, we'll shift gears slightly.
Our next lesson, "Generate a new Spring Boot project using Spring Initializr," will kick off our exploration of Spring Boot. We will move from the foundational "how it works" to the more practical "how to build with it efficiently." You'll see how Spring Boot simplifies much of the configuration we've been learning about, letting you focus on building application logic.