You are here
Home > java >

Spring Bean Life Cycle Method Examples

Spring Bean Life Cycle Method ExamplesIn the context of Spring Framework, if we want to execute some code after the bean construction, then we can write that code inside the custom init() method. Similarly, if we want to execute some code just before the destruction of the bean, we can write that code insideย destroy() method. These methods are called Spring Bean Life Cycle Methods. Here in this article we will develop โ€˜Spring Bean Life Cycle Method Examplesโ€™.

The bean life cycle is managed by the spring container. When we run the program, first of all, the spring container gets started. After that, the container creates the instance of a bean as per the request, and then the required dependencies are injected. At the end, the bean is destroyed when the spring container is closed. In continuation to โ€˜Spring Core Tutorialsโ€˜ topic, now letโ€™s discuss about โ€˜Spring Bean Life Cycle Method Examplesโ€™ and the related concepts step by step.

What is Bean Life Cycle?

When we talk about the life cycle of a living thing as a general term, It means when & how it is born, how & what it has done throughout its life, and when & how it has died. Similarly, the bean life cycle refers to when & how the bean is instantiated, what action it performs until it lives, and when & how it is destroyed.

What are Spring Bean Life Cycle Methods?

When a Spring Container creates a bean, it provides two methods to every bean by default. These are:

1) public void init()ย  ย  ย 2) public void destroy()

However, we can change the names of methods, but method signature must be the same. If we remain the method names as it is, the code becomes easy to understand.

When are the Bean Life Cycle Methods called?

The init() method is called after bean construction and before requesting an object. destroy() method is called just before the destruction of a bean.

What are the purpose of implementing Life Cycle Methods?ย 

init(): If we want to initialize anything such as loading some configurations, creating database connections, we can write that code in init() method.

destroy(): If we want to cleanup something such as closing database connections, we can write that code in destroy() method.

What are the different approaches to configure Spring Bean Life Cycle Methods?

There are three approaches to configure Spring Bean Life Cycle methods:

1) Using XML (also called Declarative Approach)

2) Using Spring Interfaces (also called Programmatic Approach)

3) Using Annotations

Now letโ€™s create some examples to understand Spring Bean Life Cycle methods.

How to implement Spring Bean Life Cycle Method Examples Using XML Configuration?

Letโ€™s start implementing an example using XML configuration step by step:

Step#1: Create a Project in Eclipse/STS

1) Open your Eclipse IDE, then go to new -> project-> Maven Project and click on next.

2) Click on โ€˜Create a simple Project (Skip archetype selection)โ€™

3) Provide the values of Group Id & Artifact Id. Group Id uniquely identifies your project among all. So it may be something like com.dev.spring.lifecycle. Artifact Id may be something like project name, so here we can put artifact id as SpringLifeCycleExample.

4) Click on โ€˜Finishโ€™. You will get a new maven based project.

Step#2: Modify pom.xml

When you create a new project, you will find a file called pom.xml. In this file we need to provide the dependency of basic spring jars. Copy the below code and paste it in your pom.xml inside <dependencies> tag. You can choose to provide the latest stable version of your own choice.

<dependency>
ย  ย  ย <groupId>org.springframework</groupId>
ย  ย  ย <artifactId>spring-core</artifactId>
ย  ย  ย <version>4.1.4.RELEASE</version>
</dependency>

<dependency>
ย  ย  <groupId>org.springframework</groupId>
ย  ย  <artifactId>spring-context</artifactId>
ย  ย  <version>4.1.4.RELEASE</version>
</dependency>

Once you save the pom.xml file, all required jars will get downloaded automatically.

Step#3: Create a Pojo Classย 

Letโ€™s create a package com.dev.spring.bean.lifecycle inside โ€˜src/main/javaโ€™ folder of your project explorer. Then create a POJO class Book.java under this package as shown below.

package com.dev.spring.bean.lifecycle;

public class Book {

   private Integer id;
   private String name;

   public Book() {
      super();
   }
 
   public Integer getId() {
      return id;
   }
   public void setId(Integer id) {
      System.out.println("Setting Book Id");
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }

   @Override
   public String toString() {
      return "Book [Id=" + Id + ", name=" + name + "]";
   }

   public void initMethod() {
      System.out.println("Inside init() method");
   }

   public void destroyMethod() {
      System.out.println("Inside destroy() method");
   }
}

Here, we have created two methods initMethod() and destroyMethod(), which will be our bean life cycle methods.

Step#4: Create a configuration file (config.xml)

This file is important as we are using XML method to implement bean life cycle methods. Apart from defining the bean, most importantly, we need to provide init-method name and destroy-method name which we provided in our class as shown below.

<?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 definitions here -->

<bean name="book" class="com.dev.spring.bean.lifecycle.Book"
                  init-method="initMethod" destroy-method="destroyMethod">
  <property name="id" value="94568"/>
  <property name="name" value="Spring In Action"/>
</bean>

</beans>

While creating XML configuration file, we can refer Spring docs for XSD Configuration to get the proper schema definitions. Since we are going to use beans & context module of Spring framework, we have added schema definitions only for them.

Step#5: Create a Test class

Letโ€™s create a test class where we will define a main() method to test our results.

package com.dev.spring.bean.lifecycle;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

public static void main(String[] args) {

   // ApplicationContext ctx= new ClassPathXmlApplicationContext("com/dev/spring/bean/lifecycle/config.xml");
   AbstractApplicationContext ctx= new ClassPathXmlApplicationContext("com/dev/spring/bean/lifecycle/config.xml");
   Book book = (Book) ctx.getBean("book");
   System.out.println(book);

   //registering shutdown hook
   ctx.registerShutdownHook();
   }
}

In order to use destroy method of spring bean life cycle, we need to call registerShutdownHook() method. This method is available in AbstractApplicationContext. Hence, we are using AbstractApplicationContext interface in place of ApplicationContext interface to get spring context.

Step#6: Test Output

Once you run the application, output will look like below:

Setting Book Id
Inside init() method
Book [Id=94568, name=Spring In Action]
Inside destroy() method

Form the output, it is clear that first of all properties are getting set, then init() method is called. At the last destroy() method is called.

How to implement Spring Bean Life Cycle Method Examples Using Spring Interfaces?

Spring Framework provides two interfaces to implement Spring Bean Life Cycle methods:

InitializingBean

DisposableBean

Step#1: Create a Project & Update pom.xml

Please complete Step#1 & Step#2 from the previous section if not already done.

Step#2: Create a Pojo Class

Here, we have to create a POJO class that will implement Spring provided two interfaces: InitializingBean & DisposableBean as shown below.ย 

package com.dev.spring.bean.lifecycle;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class Employee implements InitializingBean, DisposableBean{

   private Long id;
   private String name;

   public Employee() {
     super();
   }

   public Long getId() {
      return id;
   }
   public void setId(Long id) {
      System.out.println("Setting Id Of the Employee");
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }

   @Override
   public String toString() {
      return "Employee [id=" + id + ", name=" + name + "]";
   }

   public void afterPropertiesSet() throws Exception {

      System.out.println("Inside afterPropertiesSet() method");
   }

   public void destroy() throws Exception {

      System.out.println("Inside destroy() method");
   }
}ย  ย  ย  ย  ย  ย ย 

When you implement two interfaces, compiler will expect from you to override spring life cycle methods: afterPropertiesSet() and destroy().

Step#3: Create a configuration file (config.xml)

This file is important as we are going to define bean here.

<?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 definitions here -->

<bean name="employee" class="com.dev.spring.bean.lifecycle.Employee">
    <property name="id" value="74568"/>
    <property name="name" value="Employee-1"/>
</bean>

</beans>

While creating XML configuration file, we can refer Spring docs for XSD Configuration to get the proper schema definitions. Since we are going to use beans & context module of Spring framework, we have added schema definitions only for them.

Step#4: Create a Test class

Letโ€™s create a test class where we will define a main() method to test our results.

package com.dev.spring.bean.lifecycle;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

public static void main(String[] args) {

   // ApplicationContext ctx= new ClassPathXmlApplicationContext("com/dev/spring/bean/lifecycle/config.xml");
   AbstractApplicationContext ctx= new ClassPathXmlApplicationContext("com/dev/spring/bean/lifecycle/config.xml");
   Employee employee = (Employee) ctx.getBean("employee");
   System.out.println(employee);

   //registering shutdown hook
   ctx.registerShutdownHook();
   }
}

In order to use destroy method of spring bean life cycle, we need to call registerShutdownHook() method. This method is available in AbstractApplicationContext. Hence, we are using AbstractApplicationContext interface in place of ApplicationContext interface to get spring context.

Step#5: Test Output

Once you run the application, output will look like below:

Setting Id Of the Employee
Inside afterPropertiesSet() method
Employee [id=74568, name=Employee-1]
Inside destroy() method

Form the output, it is clear that first of all properties are getting set, then afterPropertiesSet() method is called. At the last destroy() method is called.

How to implement Spring Bean Life Cycle Method Examples Using Annotations?

Spring framework provides two annotations to implement bean life cycle in Spring:

@PostConstruct

@PreDestroy

Annotation names are self explanatory. PostConstructs means after constructing the properties of the class. PreDestroy means before destroying the bean.

Step#1: Create a Project in Eclipse/STSย 

Please complete Step#1 from the previous sections if not already done.

Step#2: Modify pom.xml

When you create a new project, you will find a file called pom.xml. In this file we need to provide the dependency of basic spring jars. Copy the below code and paste it in your pom.xml inside <dependencies> tag. You can choose to provide the latest stable version of your own choice.

One important point here is to note that both the @PostConstruct and @PreDestroy annotations do not belong to the Spring. They are part of Jave EE (JEE) library and exits in common-annotations.jar. Since Java EE was deprecated in Java 9, and removed in Java 11, we have to add an additional dependency โ€˜javax.annotation-apiโ€™ to use these annotations. If you are using Java 8 or lower versions, there is no need to include this dependency.

<dependency>
ย  ย  ย <groupId>org.springframework</groupId>
ย  ย  ย <artifactId>spring-core</artifactId>
ย  ย  ย <version>4.1.4.RELEASE</version>
</dependency>

<dependency>
ย  ย  <groupId>org.springframework</groupId>
ย  ย  <artifactId>spring-context</artifactId>
ย  ย  <version>4.1.4.RELEASE</version>
</dependency>

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

Once you save the pom.xml file, all required jars will get downloaded automatically.

Step#2: Create a Pojo Class

Here, we have to create a POJO class that will have two life cycle methods where we will use annotations: @PostConstruct & @PreDestroyย as shown below.ย 

package com.dev.spring.bean.lifecycle;

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

public class Person {

   private String name;
   private Integer age;

   public Person() {
      super();
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
     this.name = name;
   }

   public Integer getAge() {
      return age;
   }

   public void setAge(Integer age) {
      System.out.println("Setting Person's Age");
      this.age = age;
   }

   @Override
   public String toString() {
      return "Person [name=" + name + ", age=" + age + "]";
   }

   @PostConstruct
   public void initMethod() {
      System.out.println("Inside init method");
   }

   @PreDestroy
   public void destroyMethod() {
      System.out.println("Inside destroy method");
   }
}

ย When you implement two life cycle methods, donโ€™t forget to annotate them.

Step#3: Create a configuration file (config.xml)

In addition to defining the bean, itโ€™s important to specify the < context:annotation-config/> tag here. It will enable annotations in the application. Please note that without this tag, you will not be able to use annotations in your application.

<?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 definitions here -->
<context:annotation-config/>

<bean name="person" class="com.dev.spring.bean.lifecycle.Person">
    <property name="age" value="24"/>
    <property name="name" value="Person-1"/>
</bean>

</beans>

While creating XML configuration file, we can refer Spring docs for XSD Configuration to get the proper schema definitions. Since we are going to use beans & context module of Spring framework, we have added schema definitions only for them.

Step#4: Create a Test class

Letโ€™s create a test class where we will define a main() method to test our results.

package com.dev.spring.bean.lifecycle;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {

public static void main(String[] args) {

   // ApplicationContext ctx= new ClassPathXmlApplicationContext("com/dev/spring/bean/lifecycle/config.xml");
   AbstractApplicationContext ctx= new ClassPathXmlApplicationContext("com/dev/spring/bean/lifecycle/config.xml");
   Person person = (Person) ctx.getBean("person");
   System.out.println(person);

   //registering shutdown hook
   ctx.registerShutdownHook();
   }
}

In order to use destroy method of spring bean life cycle, we need to call registerShutdownHook() method. This method is available in AbstractApplicationContext. Hence, we are using AbstractApplicationContext interface in place of ApplicationContext interface to get spring context.

Step#5: Test Output

Once you run the application, output will look like below:

Setting Person's Age
Inside init method
Person [name=Person-1, age=24]
Inside destroy method

Form the output, it is clear that first of all properties are getting set, then init() method is called. At the last destroy() method is called.

FAQ

When to use Which Approach of Spring Bean Life Cycle Methods?

The decision on the approach should be based on the specific scenario:

1) If the Spring Bean is a user-defined class, we should prefer the annotation based approach, because we can easily add annotations in the source code of user-defined classes.

2) If the Spring Bean is a predefined Java class provided by the Spring Framework, and also implementing InitializingBean, DisposableBean interfaces, then it automatically goes for interfaces approach, otherwise go with XML based approach by identifying the life cycle methods.

3) If the Spring Bean is a pre-defined class provided by third party or JDK/JEE, then we should go with the XML approach by identifying the life cycle methods.

Can we define custom initialization and destruction methods for Spring beans with Java configuration (no XML)?

Yes, we can define custom initialization and destruction methods in Java configuration using the @Bean annotationโ€™s initMethod and destroyMethod attributes as shown below.

@Bean(initMethod = "customInit", destroyMethod = "customDestroy")
public MyBean myBean() {
   return new MyBean();
}

What happens if a bean implements both InitializingBean and defines a custom initMethod in Spring?

If a bean implements InitializingBean and also specifies a custom initMethod, both methods will be called during the initialization phase. The order of execution is first afterPropertiesSet() and then the custom initMethod().

ย 

ย 

ย 

Leave a Reply


Top