This article has participated in the Denver Nuggets Creators Camp 3 “More Productive writing” track, see details: Digg project | creators Camp 3 ongoing, “write” personal impact.

Spring Bean lifecycle callback

Beans in Spring are created with the Spring container, and when the Spring container is shut down, the corresponding beans disappear. Of course, this depends on the scope of the Bean itself, but there are usually three states: initialization, running, and closing.

In Spring, we usually need to do some extra resource processing when the Bean is first initialized or when the Bean is destroyed. Spring provides the InitializingBean and DisposableBean interfaces, calling afterPropertiesSet () for the former and destroy () for the latter so that the bean can perform certain actions as it initializes and destroys the bean.

As follows:

public class SampleInitializingBean implements InitializingBean {

    @Override
    public void afterPropertiesSet(a) throws Exception {
    log.info("inside afterPropertiesSet"); }}Copy the code
public class SampleDisposableBean implements DisposableBean {


    @Override
    public void destroy(a) throws Exception {
        log.info("destroy"); }}Copy the code

This, of course, is coupled to Spring code. We can use jSR-250’s @postConstruct and @Predestroy annotations to decouple from the Spring framework.

The third option is to use the configured init-method and destroy-method, or use the @bean’s initMethod property and the @bean’s destroyMethod property.

As follows:

    <bean id="exampleInitBean" class="com.flydean.beans.ExampleBean" 
          init-method="init" destroy-method="destroy"/>
Copy the code

Here is an example of an @bean annotation:

    @Bean(initMethod = "init",destroyMethod = "destroy")
    public ExampleBean getExampleBean(a){
        return new ExampleBean();
    }
Copy the code

You can also add a default initialization and destruction method for all beans:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
    default-init-method="init" default-destroy-method="destroy">
Copy the code

Summarize the lifecycle mechanism

Since Spring2.5, you have three ways to control the bean lifecycle:

  • InitializingBean and DisposableBean callback interfaces
  • Customize the init() and destroy() methods.
  • @postconstruct and @predestroy annotations.

If multiple lifecycle names are configured for initialization, the sequence is as follows:

  • PostConstruct method annotation
  • The afterPropertiesSet() method in the InitializingBean interface
  • Custom init() method

Destroy is also in the same order:

  • PreDestroy method annotation
  • The destroy() method inside the DisposableBean interface
  • Custom destroy() method

Startup and Shutdown callbacks

Above we talked about callbacks during bean initialization and destruction. It’s usually enough. Spring provides the Lifecycle interface if you need to manage Lifecycle objects yourself, such as when starting and stopping background processes.

public interface Lifecycle {

    void start(a);

    void stop(a);

    boolean isRunning(a);
}
Copy the code

Any Spring-managed object can implement the Lifecycle interface. When ApplicationContext receives a start or stop signal, it passes that signal to all implementations of the Lifecycle interface.

Spring provides LifecycleProcessor interface, the default implementation of this interface is DefaultLifecycleProcessor:

public interface LifecycleProcessor extends Lifecycle {

	/** * Notification of context refresh, e.g. for auto-starting components. */
	void onRefresh(a);

	/** * Notification of context close phase, e.g. for auto-stopping components. */
	void onClose(a);

}
Copy the code

OnRefresh () and onClose() will call the start () and close () methods that implement the Lifecycle interface.

If you need to implement the sequence of start and close callbacks, you can implement the SmartLifecycle interface, which provides the getPhase () method:

 public interface SmartLifecycle extends Lifecycle.Phased {

    boolean isAutoStartup(a);

    void stop(Runnable callback);
}
Copy the code

When started, the object with the lowest phase is started first. When stopped, execute in reverse order.

Gracefully close the Spring IoC container

In the case of a Spring WEB application, Spring’s Web-based ApplicationContext implementation already has code to gracefully close the Spring IoC container.

Here we consider the non-Web case where we need to register a Shutdown hook into the JVM. This ensures an elegant shutdown and calls the associated destruction methods in the singleton bean, freeing all resources.

Call ConfigurableApplicationContext registerShutdownHook of interface () to register a shutdown hook, as shown below:

    public static void main(final String[] args) throws Exception {
        ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("bean-lifecycle.xml");

        // add a shutdown hook for the above context...
        ctx.registerShutdownHook();

        // app runs here...

        // main method exits, hook is called prior to the app shutting down...
    }
Copy the code

The code in this section can refer to bean-lifecycle

See flydean’s blog for more tutorials