Spring Bean Scopes: Guide to understand the different Bean scopes


Introduction

This tutorial shows the different scopes you can assign to a Bean or a Component in Spring Framework.

It’s important to understand that a Bean definition is just a recipe to create instances of a class following the definition of this recipe. This recipe can be then used one or more times during the life cycle of the application to create an instance of the Bean.

The Bean scope is one of the main characteristics of the Bean configuration in Spring. The scope will indicate when and how is the object for the Bean definition going to be instantiated.

Spring includes 7 different Bean scopes:

  • Singleton
  • Prototype
  • Request
  • Session
  • Global session
  • Application
  • Websocket

From these, only 5 of them are available in a web-aware application.

Singleton

Singleton is the default scope for a Bean, the one that will be used if nothing else is indicated. This scope implies that Spring container will create an only shared instance of the class designated by this bean, so each time the Bean is required the same object will be injected. The instance of this Bean is stored in a cache managed by Spring.

We can use annotations to define singletons as in the following example:

As already stated, Singleton is the default scope for a Spring Bean, so it’s not necessary to define its @Scope (first example). However, for better clarity and understanding, you can highlight this fact by using the @Scope annotation as in the second example.

The following test shows the behavior of a singleton:

The behavior for @Component (or any of its extensions) annotated classes is the same as for regular Beans, they will be singleton unless configured differently.

For example, a @RestController as the following:

Will assert the following test:

Prototype

In the Prototype scope, Spring container will create a new instance of the object described by the bean each time it receives a request. One of the basic rules stated in Spring’s documentation is to use Prototype scoped beans when working on an environment where there is session management (Stateful) and use Singleton scope when working on environments without session management (Stateless), however there are many other more and different use cases.

It’s important to highlight that the Spring container doesn’t take responsibility for what happens to the instances of the objects received when requesting a bean. This means that it’s the developer’s task to perform clean up and free the resources referenced by the object defined by the Bean.

Same as with Singleton scope, we can define a bean with Prototype scope using annotations as follows::

The next test shows the behavior of a prototype:

Singleton Beans with injected Prototype Beans

It’s very important to highlight that when you define a Singleton Bean with dependencies or encapsulated Prototype Beans, injection happens when the Singleton object is instantiated so injection just happens once. Thus the injected object defined by the Prototype Bean will always be the same instance even though it was defined with a Prototype scope.

For example, we can define a class with an injected Bean as follows:

We define the following Beans:

The first Bean (Sample) has a Prototype scope and will be injected in the second (SampleAutowired) which has a Singleton scope. As explained in the previous paragraphs, the expected behavior is that each time we request a SampleAutowired, the instance of Sample will be the same even when it has a Prototype scope because it was instantiated and assigned only once when SampleAutowired (Singleton) was first instantiated..

This is proved in the following test:

Web-aware application scopes

As mentioned in the introduction, the rest of the scopes are only available for web-aware applications.

Request

The Spring container will create a new instance of the object defined by the Bean each time it receives an HTTP request.

To define a Bean with this scope we can use the following annotations depending on if it’s a Bean or a Component:

The behavior for the @RestController in the previous snippet can be tested as follows:

Session

Spring container will create a new instance of the object defined by the Bean for each of the HTTP sessions (Stateful application) and will return this same instance each time it receives a request within the same session.

The behavior for the @RestController in the previous snippet can be tested as follows:

Global Session

The Global Session scope has a behavior similar to the Session scope but it’s only applicable in the context of Portlet based web applications. The Portlet specification defines a global session as a session that’s shared amongst al the Portlets that make up an application.

If this scope is used in a regular web application, the behavior of the Beans defined with this scope will be the same as if they had been defined with a Session scope.

Application

The Application scope has a behavior very similar to the Singleton scope, Spring will create a new instance fo the bean for each ServletContext. A Spring application can have several ServletContext, so the instance returned by Spring for each Bean request will be the same within the same context, but different for each of the contexts.

Websocket

The Spring container will create a new instance of the object defined by the Bean and return this instance for each request produced within the lifecycle of a Websocket.

Conclusion

This post can be used as a quick guide to understand the different scopes availabe in a Spring application. There are practical examples and unit tests to prove each of the behaviors. The full source code for this post can be found at Github.

References

https://docs.spring.io/spring/docs/4.3.12.RELEASE/spring-framework-reference/htmlsingle/#beans-factory-scopes

 

Ámbitos de una aplicación de Spring

Leave a comment

Your email address will not be published. Required fields are marked *