Spring优雅关闭之:ShutDownHook

转载自:https://blog.csdn.net/qq_26323323/article/details/89814410

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

猜你喜欢

转载自www.cnblogs.com/changxy-codest/p/11944401.html