spring lifecycle callback (do something after loading and before logging off)

Posted by julius_h on Wed, 09 Mar 2022 14:23:25 +0100

The spring lifecycle callback is on the official website https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans -The factory life cycle is explained in detail. Spring's lifecycle callback is divided into Bean's lifecycle callback and container's lifecycle callback.

1. Lifecycle callback of bean

1.1 Bean lifecycle initialization callback

1.1.1 @PostConstruct annotation

@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class A1Service{
   @PostConstruct
   public void  init(){
      System.out.println("A1Service init ... ");
   }
}

1.1.2 implement InitializingBean interface

@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public  class A3Service implements InitializingBean {
   @Override
   public void afterPropertiesSet() throws Exception {
      System.out.println("A3Service init...");
   }
}

1.1.3 specifying the init method attribute in XML

Bean Class:

public class A2Service{
   public void init(){
      System.out.println("A2Service init ... ");
   }
}

xml to configure:

<bean id="a2Service" class="stu.spring.services.A2Service" init-method="init"></bean>

1.1.4 when the above three Bean life cycle initialization callback methods all exist, there is a problem of execution sequence

At the source level, it is executed in the above order.

The bean lifecycle callback initialization is executed after the bean initialization is completed.
When multiple Bean lifecycle initialization callback methods are configured and point to the same method, the method is called only once.


1.2 Bean life cycle destruction callback

1.2.1 @PreDestroy annotation

@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class A1Service{
   @PreDestroy
   public void  destroy(){
      System.out.println("A1Service destroy ... ");
   }
}

1.2.2 implementation of DisposableBean interface

@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public  class A3Service implements DisposableBean {
   @Override
   public void destroy() throws Exception {
      System.out.println("A3Service destroy...");
   }
}

1.2.3 configure destroy method attribute in XML

Bean Class:

public abstract  class A2Service{
   public void destroy() {
      System.out.println("A2Service destroy...");
   }

}

xml to configure:

<bean id="a2Service" class="stu.spring.services.A2Service" destroy-method="destroy"></bean>

1.2.4 the order of execution when the above three Bean life cycle destruction callback methods exist

At the source level, it is executed in the above order.
When multiple Bean life cycle destruction callback methods are configured and point to the same method, the method is called once.


1.2.5 configure the default Bean's life cycle destruction callback method name

spring has a special function, which can configure the Bean's destruction callback method. The default name is close or shutdown.

In the spring source code, the AbstractBeanDefinition class has such an attribute:

public static final String INFER_METHOD = "(inferred)";

As long as the Bean's destruction method is configured, it is called abstractbeandefinition INFER_ The value of the method attribute. When the Bean is destroyed, it will call the method whose method is close or shutdown by default. If the two methods exist at the same time, it will only call the close method.
Configuration mode 1:

Specify the value of destroy method attribute in xml as the above attribute value.

<bean id="xmlConfigLifeCycle"
     class="stu.spring.lifecycle.bean.XmlConfigLifeCycle" autowire="byType"
     init-method="init" destroy-method="(inferred)"
   ></bean>

 

Configuration mode 2:
The custom Bean factory post processor modifies the value of the destroyMethodName property of the BeanDefinition object

@Component
public class CustomerBeanFactoryPostProcesser implements BeanFactoryPostProcessor {
   @Override
   public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
      BeanDefinition aService = beanFactory.getBeanDefinition("AService");
   aService.setDestroyMethodName(AbstractBeanDefinition.INFER_METHOD);
   }
}

 

2. Life cycle callback of spring container

2.1 implementation of SmartLifecycle interface

@Component
public class IocLifeCycle1 implements SmartLifecycle {
   private boolean isRunning = false;
   //IOC container initialization completion call
   @Override
   public void start() {
      System.out.println("IocLifeCycle1 start ...");
      isRunning=true;//Must be set to true, otherwise stop() will not be called
   }
   //Non web projects need to call close() or stop() shown in the container to call here
   @Override
   public void stop() {
      System.out.println("IocLifeCycle1 stop ...");

   }

   @Override
   public boolean isRunning() {
      return isRunning;
   }

   //Priority of execution when there are multiple SmartLifecycle implementation classes
   @Override
   public int getPhase() {
      return 10;
   }
}

 

The life cycle callback method of IOC container is more commonly used. When using this method to complete the life cycle of the container, the callback is directly called by the SmartLifecycle interface

default void stop(Runnable callback) {
   stop();
   callback.run();
}

Method. The callback for completing the life cycle destruction of the container in spring has a timeout setting, which is 30s by default and configurable,
Configuration mode:

<bean id="lifecycleProcessor" class="org.springframework.context.support.DefaultLifecycleProcessor">
    <property name="timeoutPerShutdownPhase" value="10000"/>
</bean>

 

2.2 implement Lifecycle interface

When using the implementation class of the Lifecycle interface to complete the Lifecycle callback of the IOC container, the start() of the calling container needs to be displayed;

@Component
public class IocLifeCycle2 implements Lifecycle {
   private boolean isRunning = false;

   @Override
   public void start() {
      System.out.println("IocLifeCycle2 start ...");
      isRunning=true;
   }
//Non web projects need to call close() or stop() shown in the container to call here
   @Override
   public void stop() {
      System.out.println("IocLifeCycle2 stop ...");
   }

   @Override
   public boolean isRunning() {
      return isRunning;
   }

}

 

Topics: Spring Spring Boot