天天看點

Spring5參考指南:Bean的生命周期管理

文章目錄

    • Spring Bean 的生命周期回調
    • 總結生命周期機制
    • startup和Shutdown回調
    • 優雅的關閉Spring IoC容器

Spring中的Bean是随着Spring容器産生的,當Spring容器關閉的時候,相應的Bean也會消失。當然這個和Bean自身的作用域範圍也有關系,但是通常都逃不過 初始化,運作,關閉這三個狀态。

在Spring中,我們通常需要在Bean剛剛初始化的時候,或者Bean被銷毀的時候做一些額外的資源處理的事情。Spring提供了InitializingBean和DisposableBean接口,前者調用afterPropertiesSet(),為後者調用destroy(),以便bean在初始化和銷毀bean時執行某些操作。

如下所示:

public class SampleInitializingBean implements InitializingBean {

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


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

當然這樣做就和Spring的代碼耦合了。我們可以使用JSR-250 的@PostConstruct和@PreDestroy注解,這樣就和Spring架構解耦了。

第三種方法就是使用配置的init-method和destroy-method,或者使用@Bean的initMethod屬性和@Bean的destroyMethod屬性。

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

下面是@Bean注解的例子:

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

也可以為所有的bean都添加一個預設的初始化方法,和銷毀方法:

<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">      

從Spring2.5之後,你有3種方式來控制bean的生命周期:

  • InitializingBean和DisposableBean回調接口
  • 自定義init() 和destroy() 方法。
  • @PostConstruct 和 @PreDestroy注解.

如果為initialization配置了多種生命周期的多個名字,那麼執行順序如下:

  • @PostConstruct 的方法注解
  • InitializingBean接口裡面的afterPropertiesSet() 方法
  • 自定義的init() 方法

同樣的Destroy也是一樣的順序:

  • @PreDestroy 的方法注解
  • DisposableBean接口裡面的destroy() 方法
  • 自定義的destroy() 方法

上面我們講了在bean初始化和銷毀的時候的回調。一般來說就已經夠用了。如果需要自己管理生命周期對象,比如啟動和停止一些背景程序的時候,Spring提供了Lifecycle接口。

public interface Lifecycle {

    void start();

    void stop();

    boolean isRunning();
}      

任何Spring管理的對象都可以實作Lifecycle接口。當ApplicationContext收到一個start或者stop信号時,他會将該信号傳遞給所有的Lifecycle接口的實作。

Spring提供了LifecycleProcessor接口,該接口的預設實作是DefaultLifecycleProcessor :

public interface LifecycleProcessor extends Lifecycle {

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

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

}      

onRefresh()和onClose()會去調用實作了Lifecycle接口的start()和close()方法。

如果需要實作啟動和關閉回調的順序,則可以實作SmartLifecycle接口,該接口提供了getPhase()方法:

 public interface SmartLifecycle extends Lifecycle, Phased {

    boolean isAutoStartup();

    void stop(Runnable callback);
}      

啟動時,具有最低phase的對象首先啟動。停止時,按相反順序執行。

如果是Spring WEB應用程式,Spring的web基礎的ApplicationContext實作,已經有代碼優雅的關閉 Spring IoC 容器。

這裡我們考慮非web情況,我們需要注冊一個shutdown hook到JVM中。這樣将保證優雅的關閉,并且在單例bean中調用相關的銷毀方法,讓所有的資源得到釋放。

調用ConfigurableApplicationContext接口中的registerShutdownHook()來注冊一個shutdown hook, 如下所示:

    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...
    }      
  • 區塊鍊從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特币等持續更新
  • Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
  • Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
  • java程式員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程

繼續閱讀