文章目錄
-
- 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版)-持續更新中,附詳細文章教程