Spring Core | Bean Scope
What is the Spring Bean Scope? The Spring Framework is responsible for creating and managing beans in its container. It is also responsible for wiring these Java Beans together to get the job done. Now, many beans can be dependent on a particular bean. Does that mean spring creates a new Java Bean each time when someone requests it? Well, it depends upon what kind of bean it is and how you configure it. This whole mechanism in a spring framework is called bean scope.
By default, all beans created in a spring container as singletons.
What is a singleton? A singleton is a class that allows only a single instance of itself to be created within a spring application context.
The beans in a spring container can be created in 6 spring bean scopes. Let us understand each of these scopes and their use-case one by one.
1. Singleton Bean Scope
As mentioned above, every bean within a spring container is singleton scope which means one instance of a bean will be created for an application context. A single instance of a bean is shared by all the Java Beans which has a reference to it. Singleton scope is ideal when the bean is stateless and is mostly used for some utility function which can be reused over and over again.
2. Prototype Bean Scope
When you are working with a mutable class that stores some state in it then singleton bean scope isn’t an ideal choice because it will be shared by multiple other beans. In that case, the prototype bean scope comes to your rescue. When you declare a bean to be of type prototype scope, Spring ensures that every time a new instance of the bean is created whenever it is retrieved from the Spring container. Let us understand how we can configure a bean to be of prototype bean scope.
//When using auto-configuration @Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class TextEditor{ ... } //When using explicit Java configuration @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public TextEditor textEditor() { return new TextEditor(); }
In the example, we are using @Scope
annotation to define Spring bean’s scope. We can use this annotation together with @Component
or @Bean
depending on how we are configuring our beans in an application. Here, we have specified prototype bean scope by using SCOPE_PROTOTYPE
constant from the ConfigurableBeanFactory
class.
3. Request and Session Bean Scope
All the bean scopes which we will be discussing from now on are used in web applications. What are Request and Session? To understand these concepts and bean scopes we will take a famous example of an E-commerce application.
We all know there’s a shopping cart in an e-commerce application that is unique for every user. Let us assume, If a shopping cart is a singleton bean then all the users will share a common shopping cart and will keep on adding the products to the same shopping cart. On the other hand, if we define a shopping cart as a prototype bean scope then every reference to a shopping cart will be a new instance which definitely we would not want.
For a user, shopping cart bean should be attached to him and should be consistent during his session in an application. Hence for this use case session bean scope makes sense. To create a session bean scope we will use @Scope
annotation just like we did above for prototype bean scope.
@Component @Scope( value=WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.INTERFACES) public ShoppingCart cart() { ... }
In the example, we tell Spring to create an instance of ShoppingCart
bean for each session in an e-commerce application. There will be multiple instances of ShoppingCart
bean, each will be associated with the user’s session. Similarly, if we have certain use-case where bean’s lifecycle should only be restricted to a user’s request then we will be creating a request bean scope in a similar fashion.
@Component @Scope( value=WebApplicationContext.SCOPE_REQUEST, proxyMode=ScopedProxyMode.INTERFACES) public LoginAction loginAction() { ... }
If you notice the above two examples, we also have used proxyMode
attribute which is set to ScopedProxyMode.INTERFACES
. Why is it required? Let us dig into it.
We have an e-commerce application which will have a bean name Store
. Bean Store
will be singleton bean scope since we will have a single instance of Store
for our application. Each user will be logged in to store and they will have their own instance of ShoppingCart
. Let us look into an example
@Component public class Store{ @Autowired public void setShoppingCart(ShoppingCart shoppingCart) { this.shoppingCart = shoppingCart; } ... }
As soon as we load the Spring application context, it will create singleton bean of Store
. Upon creation of Store
instance, Spring will try to inject its ShoppingCart
dependency using setShoppingCart()
method. But ShoppingCart
is a session bean scoped and won’t be created until a user logs in and starts a session.
Moreover, there will multiple instances of ShoppingCart
bean (one per user). Store
should handle multiple instances of ShoppingCart
for whichever session happens to be in play when Store
needs to work with the shopping cart.
So when the Spring application context is loaded, we ask Spring to load proxy ShoppingCart
instead of the actual one as shown in the above figure. The proxy will expose the same methods as ShoppingCart
. When Store
will invoke any method of ShoppingCart
it will lazily resolve the dependency and delegate the actual call to session-scoped ShoppingCart
bean. That is why in the above configuration, proxyMode
is set to ScopedProxyMode.INTERFACES
, indicating that the proxy should implement the ShoppingCart
interface and delegate to the implementation bean.
4. Application Bean Scope
Application bean scope is more or less similar to singleton bean scope. The bean is annotated as WebApplicationContext.SCOPE_APPLICATION
will be treated as application-scoped by the Spring container. The container will create one instance of this bean per web application runtime.
How it is different from Singleton? Application-scoped bean is singleton per WebApplicationContext whereas singleton-scope bean is singleton per ApplicationContext.
5. Websocket Bean Scope
What is WebSocket? When two machines are connected using the WebSocket protocol, it enables two-way communication between them. It provides a single TCP connection between them. In this type of application, HTTP is only used for the initial handshake. If the handshake succeeds, the TCP socket remains open and both machines can use it to send messages to each other.
Any bean which is annotated as WebSocket-scoped will be a singleton for that WebSocket session.
@Bean @Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_INTERFACE) public Message websocketScopedBean() { return new Message(); }
Conclusion
In this article, we discussed 6 built-in bean scopes that the Spring framework provides. Each bean scope is meant for different use-cases depending upon the application requirement. Spring also provide out of the box Custom Thread Scope which acts as a singleton within a thread. We didn’t discuss this scope in this post. Let me know if you want me to cover this. I hope by now, we are clear with the bean scope concepts in Spring.
So with this, we will mark the end of the spring core tutorial for beginners. I hope by now you have got the basic idea about what is spring framework all about and how we can use it to build java based applications. Next, we will be discussing spring boot and how it revamped the spring architecture.