The Spring Framework: Ep. 5 - Bean Scope
In the last 2 episodes, we have learned about the Spring Beans and how to configure them. The Spring IoC container creates the bean, wires them, and manages their complete life cycle from creation to destruction.
In this episode, we will learn about the different scopes of the Spring Beans. We will also learn how to configure the scope of the Spring Beans.
What is Bean Scope?
The bean scope defines the life cycle and visibility of a bean instance. In Spring, bean scope is used to decide which type of bean instance should be returned from the Spring container back to the caller.
Up until now, we have used the default scope of the Spring Beans. The default scope of the Spring Beans is Singleton. It means that the Spring IoC container creates only one instance of the bean and returns the same object reference whenever that bean is requested.
Spring Bean Scopes
Spring framework supports the following five scopes, three of which are available only if you use a web-aware ApplicationContext:
Singleton: This scopes the bean definition to a single instance per Spring IoC container (default).
Prototype: This scopes a single bean definition to have any number of object instances.
Request: This scopes a bean definition to an HTTP request. Only valid in the context of a web-aware Spring ApplicationContext.
Session: This scopes a bean definition to an HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.
Application: A component whose lifecycle is bound to the current web application. Only valid in the context of a web-aware Spring ApplicationContext.
Web-aware scopes (request, session, and application) are only available if you use a web-aware Spring ApplicationContext implementation such as AnnotationConfigServletWebServerApplicationContext.
As the name suggests, Request scope is used to create a new bean instance for each HTTP request. Similarly, Session scope is used to create a new bean instance for each HTTP session. The application scope is used to create a new bean instance for each web application.
Specifying Bean Scope
We can specify the bean scope using the @Scope
annotation. The @Scope
annotation can be applied to a class level or a method level. If we apply the @Scope
annotation at the class level, it will be applied to all the methods of that class. If we apply the @Scope
annotation at the method level, it will only be applied to that method.
It can be used both with the @Component
annotation and with the @Bean
annotation.
Let’s understand this with the help of an example. We will create a new class called MyBean and annotate it with the @Component
annotation. We will also specify the scope of the bean using the @Scope
annotation.
@Component
@Scope("singleton")
public class SingletonBean {
public MyBean() {
System.out.println("MyBean Initialized via Constructor at " + new Date());
}
}
In the above example, we have specified the scope of the bean as a singleton. It means that the Spring IoC container will create only one instance of the bean and return the same object reference whenever that bean is requested.
@Component
@Scope("prototype")
public class PrototypeBean {
public PrototypeBean() {
System.out.println("PrototypeBean Initialized via Constructor at " + new Date());
}
}
We have specified the scope of the bean as the prototype. The Spring IoC container will create a new instance of the bean whenever that bean is requested.
@Configuration
@ComponentScan(basePackages = {"com.cristianrita.beanscope"})
public class MyConfig {
}
public class MyApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
for (int i = 0; i < 10; i++) {
context.getBean("singletonBean");
context.getBean("prototypeBean");
}
}
}
When running the above application, we will see the following output in the console:
SingletonBean created via constructor at 11:43:36.899042
PrototypeBean created via constructor at 11:43:36.921982
PrototypeBean created via constructor at 11:43:36.922217
PrototypeBean created via constructor at 11:43:36.922272
PrototypeBean created via constructor at 11:43:36.922318
PrototypeBean created via constructor at 11:43:36.922361
PrototypeBean created via constructor at 11:43:36.922405
PrototypeBean created via constructor at 11:43:36.922451
PrototypeBean created via constructor at 11:43:36.922493
PrototypeBean created via constructor at 11:43:36.922534
PrototypeBean created via constructor at 11:43:36.922577
You can see that the Spring IoC container created only one instance of the SingletonBean. However, it created a new instance of the PrototypeBean whenever it was requested. The singleton bean is eagerly initialized by the Spring IoC container when the application is started. The final version of this app is available on GitHub.
Prototype Scope
The prototype scope is the opposite of the singleton scope. The Spring IoC container creates a new instance of the bean whenever that bean is requested. There are a few situations when this behavior is desirable:
stateful beans - when the bean contains some state that should not be shared with other beans of the same type.
thread safety - when the bean is not thread-safe, each concurrent thread should get its instance of the bean.
dynamic configuration - when the bean configuration is dynamic, for example, the bean is configured based on the user input. Using the prototype scope allows us to create new instances with updated configurations without affecting the other beans.
resource management - when the bean uses a resource that needs to be released, for example, a database connection, a network socket, or a file handle. Using the prototype scope allows us to create new instances with new resources that can be released without affecting the other beans.
Web-aware Scopes
By using web-aware scopes, you can leverage the HTTP requests and sessions to manage the state and availability of your beans in a web application. They are useful in various situations. For example, you can use the session scope to store user-specific data across multiple HTTP requests within the same session such as authentication details, user preferences, etc. We won’t go into the details of web-aware scopes in this episode, but you should be aware of their existence. Projects like Spring MVC or SpringSecurity use these scopes extensively.
Custom Scopes
If the built-in scopes don’t meet your needs, you can create your custom scopes. To create a custom scope, you need to implement the Scope interface.
Conclusion
In this episode, we learned about the different scopes of the Spring Beans. The default scope of the Spring Beans is Singleton. It means that the Spring IoC container creates only one instance of the bean and returns the same object reference whenever that bean is requested. We also learned how to configure the scope of the Spring Beans using the @Scope
annotation. The prototype scope is the opposite of the singleton scope. The Spring IoC container creates a new instance of the bean whenever that bean is requested. Web-aware scopes are useful in a web application.