Learnitweb

Spring Bean Scopes

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:

ScopeDescription
singletonThis is the default scope. Scopes a single bean definition to a single object instance for each Spring IoC container.
prototypeScopes a single bean definition to any number of object instances.
requestScopes 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.
sessionScopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
applicationScopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
websocketScopes 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 the org.springframework.web.context.request.RequestContextListener. This can be done programmatically by using WebApplicationInitializer interface or adding declaration in a web.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.