Spring - Bean Scopes

[Updated: Aug 9, 2016, Created: Dec 5, 2015]

Scope of a bean determines the life span of a bean instance per container. There are two core scopes

  1. singleton : Only one instance of bean per Spring container (here container mean per org.springframework.context.ApplicationContext). That means regardless of how many times, we access/inject the bean there will be only one instance provided by the container. This is the default one. This is different than Java famous singleton design pattern in that there's one Spring singleton per spring container, whereas, there's one Java singleton per JVM level.
  2. prototype : A new instance of a bean is created, each time it's injected to some other bean or accessed via the container (springContext.getBean(...)). In what situations should we use this scope? The answer is, whenever calling code wants to set some personalized session information among multiple method calls on that bean. On the other hand a singleton is not and should not be aware of a caller specific session. In that sense we can say singletons are stateless (suitable for a service, DAO or controller etc) , whereas prototypes are stateful with respect to a particular calling session (for example shopping cart, wizard like steps etc). Why don't we create such beans ourselves using new operator rather than registering it to the Spring container? Yes we should if we can, but what if we want to conveniently have Spring to do some DI for us. Well, then of course we should use this scope.

The @Scope annotation

There are two ways to use @Scope annotation to assign the scopes to beans. We are going to mention only Java-config way of assigning scopes here.

Using on bean factory methods of @Configuration class :

@Scope is used in @Configuration annotated class's method. These methods should primarily be annotated with @Bean.

Using on classes annotated with @Component:

@Scope is used on component classes. This classes should be scanned by Spring at startup if @ComponentScan along with packages to scan is defined on @Configuration class.

Example Project

Following example demonstrates the default singleton and prototype scopes. AppMain#main creates a registration form simulator. It asks user to enter registration information on command line. It does some validations on entered values and keep the same prototype bean session (UserRegistrationBean) unless user successfully correct all validation errors. Please notice how new instance of UserRegistrationBean is created on each call of context.getBean(UserRegistrationBean.class)

Dependencies and Technologies Used :

  • Spring Context 4.2.3.RELEASE: Spring Context.
  • JDK 1.8
  • Maven 3.0.4

Spring Scopes Example Select All Download
  • spring-scopes
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • bean
                • service

No Pre Destroy callback for Prototype

Spring does not manage the complete lifecycle of a prototype bean. The container instantiates, configures, a prototype bean instance, and hands it to the client, with no further record of the instance. That's the reason, the prototype bean's method annotated with PreDestroy will never be called. The initialization lifecycle callback methods (@PostConstruct) are always called on all objects regardless of scope.

Injecting Beans of different scopes

We saw in above example that we injected two singleton scoped beans (RegistrationService and UserRegistrationValidator to prototype scoped bean (UserRegistrationBeanImpl). We should always inject a bean of wider scope (e.g. a singleton) into a bean of narrower scope (e.g. a prototype bean), but not the other way around. Since a singleton is created only once, it's not possible to get a new instance of the already injected prototype bean whenever we want to use it in different methods. There are various solutions. We will cover that in next tutorial.

Bean Scopes in Web Aware ApplicationContext

Following are the three scopes available, if spring application loaded using WebApplicationContext

  1. request: One instance per HTTP request, i.e. every new HTTP request will have its own instance of the bean.
  2. session: One instance per HTTP session.
  3. globalSession: One instance per global HTTP session. Typically only valid when used in a portlet context.

See Also