Spring優雅關閉之:ShutDownHook

轉載自:http://www.javashuo.com/article/p-wechjgnv-bg.htmlide

 

2020/02/26從新編輯一下函數

前面介紹ShutDownHook的基本使用方法,可是沒有清楚的表述如何在SpringBoot中運用,這裏咱們來補充一下:this

查閱SpringBoot官方文檔有這麼一段描述:spa

 

1.10. Application Exit

 

Each SpringApplication registers a shutdown hook with the JVM to ensure that the ApplicationContext closes gracefully on exit. All the standard Spring lifecycle callbacks (such as the DisposableBean interface or the @PreDestroy annotation) can be used..net

 

官方介紹了兩種方法:code

1. 直接實現DisposableBean接口,實現destroy方法便可對象

@Slf4j @Component public class CustomShutdownHook implements DisposableBean { @Override public void destroy() throws Exception { } }

 

2. 在方法上使用@PreDestroy註解,相似@PostConstruct註解使用方法。blog

  

1. Runtime.addShutDownHook(Thread hook)

// 建立HookTest,咱們經過main方法來模擬應用程序
public class HookTest { public static void main(String[] args) { // 添加hook thread,重寫其run方法
        Runtime.getRuntime().addShutdownHook(new Thread(){ @Override public void run() { System.out.println("this is hook demo..."); // TODO
 } }); int i = 0; // 這裏會報錯,咱們驗證寫是否會執行hook thread
        int j = 10/i; System.out.println("j" + j); } }

 

2. Runtime.addShutDownHook(Thread hook)應用場景

    * 程序正常退出接口

    * 使用System.exit()生命週期

    * 終端使用Ctrl+C觸發的中斷

    * 系統關閉

    * OutofMemory宕機

    * 使用Kill pid殺死進程(使用kill -9是不會被調用的)

 

3. Spring如何添加鉤子函數

// 經過這種方式來添加鉤子函數
ApplicationContext.registerShutdownHook(); // 經過源碼能夠看到,
@Override public void registerShutdownHook() { if (this.shutdownHook == null) { // No shutdown hook registered yet.
        this.shutdownHook = new Thread() { @Override public void run() { synchronized (startupShutdownMonitor) { doClose(); } } }; // 也是經過這種方式來添加
        Runtime.getRuntime().addShutdownHook(this.shutdownHook); } } // 重點是這個doClose()方法
 
protected void doClose() { // Check whether an actual close attempt is necessary...
    if (this.active.get() && this.closed.compareAndSet(false, true)) { if (logger.isInfoEnabled()) { logger.info("Closing " + this); } LiveBeansView.unregisterApplicationContext(this); try { // Publish shutdown event.
            publishEvent(new ContextClosedEvent(this)); } catch (Throwable ex) { logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex); } // Stop all Lifecycle beans, to avoid delays during individual destruction.
        if (this.lifecycleProcessor != null) { try { this.lifecycleProcessor.onClose(); } catch (Throwable ex) { logger.warn("Exception thrown from LifecycleProcessor on context close", ex); } } // Destroy all cached singletons in the context's BeanFactory.
 destroyBeans(); // Close the state of this context itself.
 closeBeanFactory(); // Let subclasses do some final clean-up if they wish...
 onClose(); // Switch to inactive.
        this.active.set(false); } }

能夠看到:doClose()方法會執行bean的destroy(),也會執行SmartLifeCycle的stop()方法,咱們就能夠經過重寫這些方法來實現對象的關閉,生命週期的管理,實現平滑shutdown

相關文章
相關標籤/搜索