1. Introduction
Spring Bean scopes are one of the first things we encounter when we start working with Spring. This quick tutorial will explain in short all of the available Spring Bean Scopes.
Spring supports many bean scopes, until recently the only available scopes were as follows:
- singleton
- prototype
- request
- session
- global-session
Now, we have two additional Spring bean scopes that were brought to us by the newest Spring release:
- application
- websocket
In the following text, we'll discuss their differences and show how to configure beans to use one of these scopes.
2. Singleton Scope
This scope means that only one instance of the bean will be created by the IoC container. This means that all requests and references to that bean will refer to this specific one instance. Singleton is the default bean scope in Spring. It's a rule to use singleton scope for stateless beans.
In XML configuration, we would define the singleton scope as:
<bean id = "beanId" class = "beanClass" scope = "singleton">
..other bean configuration...
</bean>
If we're using annotation-based configuration as in Spring Boot, we can set bean to be singleton this way:
@Bean
@Scope("singleton")
public MyBean myBeanSingleton() {
return new MyBean();
}
Notice that we can also use constant instead of the"singleton" string:
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
3. Prototype scope
This scope is completely different from the singleton because a new instance of the bean is created by the IoC container every time that bean is requested. It's a rule to use prototype scope for stateful beans. In case we're using XML-based configuration, we'll configure a prototype-scoped bean like this:
<bean id = "beanId" class = "beanClass" scope = "prototype">
..other bean configuration...
</bean>
If we're using annotation-based configuration as with Spring Boot, we can configure bean to have a prototype scope like this:
@Bean
@Scope("prototype")
public MyBean myBeanPtototype() {
return new MyBean();
}
We can change the"prototype" string with constant this way:
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
4. Request scope
This scope is used in web-aware Spring Application Context. The idea of this bean scope is to have one instance of the bean per HTTP request.
<bean id = "beanId" class = "beanClass" scope = "request">
..other bean configuration...
</bean>
In case we're using annotation-based configuration, we can do something like this:
@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public MyBean myBeanRequest() {
return new MyBean();
}
Notice here that we're using the proxyMode parameter that is necessary when we define request scope with the @Scope parameter. It's because there is no active request when the Application context is initialized. This way, Spring creates a proxy object to be injected as a dependency, and our bean will be instantiated when the request happens.
There's also a shorter version for this configuration in the shape of the @RequestScope annotation.
@Bean
@RequestScope
public MyBean myBeanRequest() {
return new MyBean();
}
5. Session scope
This is also a scope that's used in the web-aware Application Context. It's created per every HTTP session and is present during the whole HTTP session lifecycle.
To define session scope through XML configuration file, we should do something like this:
<bean id = "beanId" class = "beanClass" scope = "session">
..other bean configuration...
</bean>
Notice that, as in the request scope, we need proxyMode parameter - this will create a proxy object that will be used for dependency injection until the session is opened and instance of the session-scoped bean created. Now, let's see how to define bean with session scope:
@Bean
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public MyBean myBeanSession() {
return new MyBean();
}
As with request scope, we have a shortcut for this annotation:
@Bean
@SessionScope
public MyBean myBeanSession() {
return new MyBean();
}
6. Global Session Scope
This scope is valid only in a web-aware Application Context. It is defined as one per global HTTP session lifecycle and is used in portlet applications. Since portlet applications have a number of portlets, and those portlets have their own sessions, sometimes is necessary to have global variables available to all portlets. This is where the global session scope is used.
To define Spring bean with this scope using XML, we should do the following:
<bean id = "beanId" class = "beanClass" scope = "globalSession">
..other bean configuration...
</bean>
7. Application Scope
The application scope is one of two scopes introduced in the newest version of Spring. It creates one bean instance for the lifecycle of the Servlet Context.
@Bean
@Scope(
value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public MyBean myBeanApplication() {
return new MyBean();
}
Notice that here also we use proxyMode parameter for the same reason as with request or session scope. There's shorter version of this bean definition using @ApplicationScope annotation and it goes like this:
@Bean
@ApplicationScope
public MyBean myBeanApplication() {
return new MyBean();
}
8. Websocket Scope
This scope means that one bean will be created per the Websocket lifecycle. It behaves like a singleton but is bound strictly to the WebSocket session. We can define it this way:
@Bean
@Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
public MyBean myBeanWebsocket() {
return new MyBean();
}
9. Conclusion
In this tutorial, we discussed Spring bean scopes - singleton, prototype, session,session-global, application, and websocket.