1. Introduction
A bean definition acts like a recipie for creating the actual instances of the the class. You can control dependencies, configuration values and the scope of the objects created from a particular bean definition.
The Spring Framework supports six scopes, four of which are available only if you use a web-aware ApplicationContext
. You can also create a custom scope. Following is the list of supported scopes:
Scope | Description |
singleton | This is the default scope. Scopes a single bean definition to a single object instance for each Spring IoC container. |
prototype | Scopes a single bean definition to any number of object instances. |
request | Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created from a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext. |
session | Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext. |
application | Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext. |
websocket | Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext. |
Note: There is another scope, thread scope. This is not registered by default.
2. Singleton Scope
The singleton scope is the default scope in Spring. Only one shared instance is managed per Spring container. All requests for a bean with that ID result in the same bean returned by the Spring container. In simple words, for a singleton scoped bean, the Spring Container creates exactly one instance of the object defined by that bean definition. This single instance is stored in a cache of such singleton beans, and all subsequent requests and references for that named bean return the cached object.
Spring’s concept of a singleton bean is different from the singleton pattern defined in the Gang of Four(GoF) patterns. The GoF singleton creates one instance per ClassLoader whereas in case of the Singleton
bean it is one instance per container.
3. Prototype Scope
When a bean is deployed with a prototype scope, a new instance of the bean is created each time it is requested. Generally, it’s recommended to use the prototype scope for stateful beans and the singleton scope for stateless beans.
Unlike other scopes, Spring does not manage the complete lifecycle of a prototype bean. The container creates, configures, and assembles a prototype object, then provides it to the client without keeping any record of it. While initialization lifecycle callback methods are called for all objects regardless of scope, destruction lifecycle callbacks are not invoked for prototypes. It is the responsibility of the client code to clean up prototype-scoped objects and release any expensive resources they hold. To ensure that resources held by prototype-scoped beans are released, you can use a custom bean post-processor to track and clean up these beans.
In many ways, the Spring container’s role for a prototype-scoped bean is similar to the Java new operator, with all further lifecycle management being the responsibility of the client.
3.1 Singleton Beans with Prototype-bean Dependencies
When using singleton-scoped beans that depend on prototype beans, it’s important to note that dependencies are resolved at the time of instantiation. Therefore, if you inject a prototype-scoped bean into a singleton-scoped bean, a new instance of the prototype bean is created and injected into the singleton bean only once. The prototype instance is the sole instance that is ever supplied to the singleton-scoped bean.
If you need the singleton-scoped bean to obtain a new instance of the prototype-scoped bean repeatedly at runtime, direct dependency injection won’t work because it happens just once during the singleton bean’s instantiation. If you need a new instance of a prototype bean at runtime more than once, use Method Injection.
4. Request, Session, Application, and WebSocket Scopes
The request
, session
, application
, and websocket
scopes are available only in a web-aware Spring ApplicationContext
implementation (such as XmlWebApplicationContext
). If you use these scopes with regular IoC containers, such as ClassPathXmlApplicationContext
an IllegalStateException
is thrown.
4.1 Configuration
To support the request
, session
, application
, and websocket
scopes in an application, some initial configuration is required before defining beans. This type of setup is not required for singleton
and prototype
scopes. This initial setup depends on the particular Servlet environment.
- In case of Spring Web MVC, where the request is processed by
DispatcherServlet
, no setup is required. - In case of a Servlet web container, with requests processed outside of Spring’s
DispatcherServlet
, you need to register theorg.springframework.web.context.request.RequestContextListener
. This can be done programmatically by usingWebApplicationInitializer
interface or adding declaration in aweb.xml
file.
<web-app> ... <listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener> ... </web-app>
Alternatively you can use Spring’s RequestContextFilter
.
<web-app> ... <filter> <filter-name>requestContextFilter</filter-name> <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class> </filter> <filter-mapping> <filter-name>requestContextFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ... </web-app>
4.2 Request Scope
Here is an example of declaring a Request
scope bean:
@RequestScope @Component public class LoginAction { // ... }
The Spring container creates a new instance of the LoginAction
bean for each and every HTTP request. When the request finishes processing, the bean that is scoped to the request is discarded.
4.3 Session Scope
Here is an example of declaring a Session
scope bean:
@SessionScope @Component public class UserPreferences { // ... }
The Spring container creates a new instance of the UserPreferences bean for the lifetime of a single HTTP Session. When the HTTP session ends, the bean scoped to that session is also discarded.
4.4 Application Scope
Here is an example of declaring a Application
scope bean:
@ApplicationScope @Component public class AppPreferences { // ... }
The Spring container creates a new instance of the AppPreferences
bean once for the entire web application. This is different with Spring singleton bean. Spring singleton bean is per ApplicationContext
where as the Application
scope bean is per ServletContext
. There can be several ApplicationContext
in a web application. An application
scope bean is visible as a ServletContext
attribute.
4.5 WebSocket Scope
WebSocket scope is associated with the lifecycle of a WebSocket session and applies to STOMP over WebSocket applications.
5. Conclusion
Understanding Spring Bean scopes is crucial for building effective and efficient Spring applications. By defining the scope of a bean, you can control its lifecycle and behavior, ensuring that your application uses resources optimally.
By leveraging these scopes, you can optimize your Spring applications to be more responsive, resource-efficient, and tailored to specific use cases. Understanding and correctly applying bean scopes is a foundational skill for any Spring developer, enabling the creation of robust, maintainable, and high-performance applications.