The Spring bean life cycle

As long as Spring beans are required by the application, they exist within the container. For a bean to get into a usable state after instantiation, it needs to perform some initialization. Likewise, some clean up may be necessary when the bean is no longer required and is removed from the container.

Spring provides us with callback methods for the life cycle of the bean. You can have a method in your bean that runs when the bean has been created, and you can also have a method in your bean that is run when the bean is about to be destroyed.

Spring's BeanFactory manages the life cycle of beans created through the Spring IoC container. The life cycle of beans consist of callback methods, which can be categorized broadly into the following two groups:

  • Post-initialization callback methods
  • Pre-destruction callback methods

The following figure illustrates the two groups:

The Spring bean life cycle

Initialization

It represents a sequence of activities that take place between the bean instantiation and the handover of its reference to the client application:

  • The bean container finds the definition of the Spring bean in the configuration file and creates an instance of the bean
  • If any properties are mentioned, populate the properties using setters
  • If the Bean class implements the BeanNameAware interface, then call the setBeanName() method
  • If the Bean class implements the BeanFactoryAware interface, then call the setBeanFactory() method
  • If the Bean class implements the ApplicationContextAware interface, then call the setApplicationContext() method
  • If there are any BeanPostProcessors objects associated with the BeanFactory interface that loaded the bean, then Spring will call the postProcessBeforeInitialization() method before the properties for the bean are injected
  • If the Bean class implements the InitializingBean interface, then call the afterPropertiesSet() method once all the bean properties defined in the configuration file are injected
  • If the bean definition in the configuration file contains the init-method attribute, then call this method after resolving the value for the attribute to a method name in the Bean class
  • The postProcessAfterInitialization() method will be called if there are any bean post processors attached to the BeanFactory interface that loads the bean

Activation

The bean has been initialized and the dependency has been injected. Now the bean is ready to be used by the application.

Destruction

This represents the following sequence of activities:

  • If the Bean class implements the DisposableBean interface, then call the destroy() method when the application no longer needs the bean reference
  • If the bean definition in the configuration file contains the destroy-method attribute, then call this method after resolving the value for the attribute to a method name in the Bean class.

There are two important bean life cycle callback methods that are required at the time of bean initialization and its destruction.

  • Initialization callbacks
  • Destruction callbacks

Initialization callbacks

There are two ways in which you can achieve the initialization work after all necessary properties on the bean are set by the container:

  • Implementing the org.springframework.beans.factory.InitializingBean interface
  • Using init-method in the XML configuration

In the EmployeeService.java class, you'll find the following code:

package org.packt.Spring.chapter2.callbacks;

public interface EmployeeService {

   public Long generateEmployeeID();

}

Implementing the org.springframework.beans.factory.InitializingBean interface

The org.springframework.beans.factory.InitializingBean interface is used to specify a single method in a bean, as follows:

void afterPropertiesSet()throws Exception;

This method gets initialized whenever the bean containing this method is called.

In the EmployeeServiceImpl.java class, you'll find the following code:

package org.packt.Spring.chapter2.callbacks;

import org.springframework.beans.factory.InitializingBean;

public class EmployeeServiceImpl implements EmployeeService, InitializingBean {

   @Override
   public Long generateEmployeeID() {

          return System.currentTimeMillis();
   }

   @Override
   public void afterPropertiesSet() throws Exception {
         System.out.println("Employee afterPropertiesSet... ");
   }
}

In the beans.xml file, you'll find the following code:

...
<bean id="employeeServiceBean" class="org.packt.Spring.chapter2.callbacks.EmployeeServiceImpl">
</bean>
...

Here, the InitializingBean interface tells Spring that the EmployeeServiceImpl bean needs to know when it's being initialized. A method of this bean needs to be called when the bean is initialized. The InitializingBean interface has afterPropertiesSet(), which needs to be implemented, and it will be called by Spring when this bean is initialized and all properties are set. This InitializingBean interface is a marker for the bean to know that the afterPropertiesSet() method of this bean needs to be called after initialization.

Using init-method in the XML configuration

In the case of XML-based configuration metadata, you can use the init-method attribute to specify the name of the method that has a void no-argument signature, which is to be called on the bean immediately upon instantiation.

In the beans.xml file, you'll find the following code:

...
<bean id="employeeServiceBean" class="org.packt.Spring.chapter2.callbacks.xml.EmployeeServiceImpl" init-method="myInit">
</bean>
...

In the EmployeeServiceImpl.java class, you'll find the following code:

package org.packt.Spring.chapter2.callbacks.xml;

public class EmployeeServiceImpl implements EmployeeService {

   @Override
   public Long generateEmployeeID() {
          return System.currentTimeMillis();
   }

   public void myInit() {
          System.out.println("Employee myInit... ");
   }
}

Now we have init-method in the configuration beans.xml file, which will take the method name as the value from the bean. So, instead of implementing an interface to this bean, we have a simple method that is called by Spring.

Destruction callbacks

There are two ways you can do a destruction callback:

  • Implementing the org.springframework.beans.factory.DisposableBean interface
  • Using destroy-method in the XML configuration

Implementing the org.springframework.beans.factory.DisposableBean interface

The org.springframework.beans.factory.DisposableBean interface is used to specify a single method in a bean, as follows:

void destroy() throws Exception;

This method allows a bean to get a callback whenever the Spring container containing this bean is destroyed.

In the EmployeeServiceImp.java class, you'll find the following code:

package org.packt.Spring.chapter2.callbacks;

import org.springframework.beans.factory.DisposableBean;

public class EmployeeServiceImp implements EmployeeService, DisposableBean {

   @Override   public Long generateEmployeeID() {
          return System.currentTimeMillis();
   }

   @Override
   public void destroy() throws Exception {
         System.out.println("Employee destroy... ");
   }
}

In the beans.xml file, you'll find the following code:

...
<bean id="employeeServiceBean" class="org.packt.Spring.chapter2.callbacks.EmployeeServiceImpl">
</bean>
...

The DisposableBean interface has a destroy() method. If a bean implements a DisposableBean interface, then Spring will automatically call the destroy() method of that bean before actually destroying the bean.

Using destroy-method in the XML configuration

In the case of XML-based configuration metadata, you can use the destroy-method attribute to specify the name of the method that has a void no-argument signature, which is called just before a bean is removed from the container.

In the beans.xml file, you'll find the following code:

<bean id="employeeServiceBean" class="org.packt.Spring.chapter2.callbacks.xml.EmployeeServiceImpl" destroy-method="cleanUp">
</bean>

In the EmployeeServiceImpl.java class, you'll find the following code:

package org.packt.Spring.chapter2.callbacks.xml;

public class EmployeeServiceImpl implements EmployeeService {

   @Override
   public Long generateEmployeeID() {
          return System.currentTimeMillis();
   }

   public void cleanUp() {
          System.out.println("Employee Cleanup... ");
   }
}

Now we have destroy-method in the configuration beans.xml file, which will take the method name as a value from the bean. So, instead of implementing the interface to this bean, we have a simple method that is called by Spring.

In the PayrollSystem.java class, you'll find the following code:

package org.packt.Spring.chapter2.callbacks.xml;

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

public class PayrollSystem {

   public static void main(String[] args) {
         ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
         EmployeeService employeeService = (EmployeeService) context.getBean("employeeServiceBean");
         System.out.println(employeeService.generateEmployeeID());
         context.close();
   }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.243.106