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.

spring bean scope proxy
Screenshot: Spring in Action

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.