Skip to content

Spring Bean Scopes And Lifecycle#

What Is The Bean Scopes?#

  • A bean scope refers to the lifecycle of a bean that means when the object of Bean is instantiated. It will let us know:

    • How long the bean will live?
    • How many instances will be created?
    • How is the bean shared in the Spring environment?.
  • Basically, it controls the instance creation of the bean and it is managed by the Spring Container.

  • The Spring framework provides five scopes for a bean. We can use three of them only in the context of web-aware Spring ApplicationContext and the rest of the two is available for both IoC container and Spring-MVC container. The following are the different scopes provided for a bean:

    • Singleton: Only one instance will be created for a single bean definition per Spring IoC container and the same object will be shared for each request made for that bean.
    • Prototype: A new instance will be created for a single bean definition every time a request is made for that bean.
    • Request: A new instance will be created for a single bean definition every time an HTTP request is made for that bean. But Only valid in the context of a web-aware Spring ApplicationContext.
    • Session: Scopes a single bean definition to the lifecycle of an HTTP Session. But Only valid in the context of a web-aware Spring ApplicationContext.
    • Global-Session: Scopes a single bean definition to the lifecycle of a global HTTP Session. It is also only valid in the context of a web-aware Spring ApplicationContext.
  • Spring Framework provides 2 ways for configuring the bean scopes:

Default Scope - Singleton#

  • The default scope for a bean is singleton. So what is the singleton?
    • For the singleton, Spring Container creates only one instance of the bean by default.
    • This bean will be cached in memory.
    • Then whenever a new request is made for that bean, spring IOC container first checks whether an instance of that bean is already created or not. If it is already created, then the IOC container returns the same instance otherwise it creates a new instance of that bean only at the first request.

 #zoom

  • This default scope is applied for both configuring bean by XML file and annotation, so it means when we don't set the bean scope during configuring the bean with XML file or annotation, then these bean will have singleton bean scope by default.

Prototype Scope#

  • If the scope is declared prototype, then spring IOC container will create a new instance of that bean every time a request is made for that specific bean.
  • A request can be made to the bean instance either programmatically using getBean() method or by XML for Dependency Injection of secondary type. Generally, we use the prototype scope for all beans that are stateful, while the singleton scope is used for the stateless beans.

 #zoom

Singleton Prototype
Only one instance is created for a single bean definition per Spring IoC container A new instance is created for a single bean definition everytime a request is made for that bean.
Same object is shared for each request made for that bean. i.e. The same object is returned each time it is injected. For each new request a new instance is created. i.e. A new object is created each time it is injected.
By default scope of a bean is singleton. So we don’t need to declare a been as singleton explicitly. By default scope is not prototype so you have to declare the scope of a been as prototype explicitly.
Singleton scope should be used for stateless beans. While prototype scope is used for all beans that are stateful

What Is The Bean Lifecycle?#

  • The life cycle of a Spring bean is easy to understand. When a bean is instantiated, it may be required to perform some initialization to get it into a usable state. Similarly, when the bean is no longer required and is removed from the container, some cleanup may be required.
  • Though, there are lists of the activities that take place behind the scene between the time of bean Instantiation and its destruction.

 #zoom

  • Firstly, the beans are instantiated and then the actual dependencies are injected. Next, we will have some internal Spring processing that occurs with the Spring Container and then we have the option for adding our own custom initialization code. After that point the bean is ready for use and we can call methods on these beans, do work with them and so on. Then at a certain point, the containers actually shutdown, meaning our application is shutdown like context.close(). Then we also have a chance to call our custom destroy method and it will be executed before the actual application is stopped or before the actual bean life cycle is over.

Bean Lifecycle Hooks#

  • As you can see in the image above, Spring provides us two chances to add our custom codes.

    • Add custom code during bean initialization
    • Add custom code during bean destruction
  • In which, Adding custom code during bean initialization is usually used for:

    • Calling custom business logic methods.
    • Setting up handles to resources (database, sockets, file etc)
  • Adding custom code during bean destruction is usually used for:

    • Calling custom business logic method.
    • Clean up handles to resources (database, sockets, file etc).
  • Spring Framework provided for us two ways to hook our custom code during bean initialization or bean destruction

    • Using configuration XML file.
    • Using annotations.

Configure With XML File#

  • To hook our custom code during bean initialization or bean destruction by using configuration XML file, we should follow these steps:

    • Define our methods for init and destroy.
    • Configure the method names in Spring config file.
  • To configure the Spring config file for adding custom code during bean initialization and bean destruction, we will use 2 properties init-method and destroy-method respectively. The values of these methods will be the method's name in the bean that we are configuring for.

applicationContext.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="englishCoach"
          class="com.spring.core.spring.bean.scopes.and.lifecycle.EnglishCoach"
          init-method="initAdHocMethod"
          destroy-method="destroyAdHocMethod">

    </bean>

        ....

</beans>

**For "prototype" scoped beans, Spring does not call the destroy method. **

Configure With Annotations.#

  • To hook our custom code during bean initialization or bean destruction by using annotations, we should follow these steps:

    • Define our methods for init and destroy.
    • Add annotations: @PostConstruct and @PreDestroy.
  • We can use the annotation @PostConstruct and @PreDestroy on any methods in the bean.

    • If a method in the bean is added @PostConstruct annotation, then this method will be executed after the constructor and after the injection of dependencies.
    • If a method in the bean is added @PreDestroy annotation , then this method will be executed before the bean is destroyed.
EnglishCoach.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.spring.core.spring.bean.scopes.and.lifecycle.annotation;  

import org.springframework.stereotype.Component;  

import javax.annotation.PostConstruct;  
import javax.annotation.PreDestroy;  

@Component  
public class EnglishCoach implements Coach {  

    @Override  
    public String getDailyHomeWork() {  
        return "Spend 1 hour to practise Speaking Skill!";  
    }  

    @PostConstruct  
    public void initAdHocMethod() {  
        System.out.println("EnglishCoach: The initAdHocMethod() is called!");  
    }  

    @PreDestroy  
    public void destroyAdHocMethod() {  
        System.out.println("EnglishCoach: The destroyAdHocMethod() is called!");  
    }  

}
  • The table below contains some special notes when we use @PostConstruct and @PreDestroy on methods.
Special Notes Description
Access modifier The method can have any access modifier (public, protected, private)
Return type The method can have any return type. However, "void' is most commonly used. If you give a return type just note that you will not be able to capture the return value. As a result, "void" is commonly used.
Method name The method can have any method name.
Arguments The method can not accept any arguments. The method should be no-arg.

See Also#

References#