Spring优雅关闭之:ShutDownHook
2020/02/26重新编辑⼀下
前⾯介绍ShutDownHook的基本使⽤⽅法,但是没有清楚的表述如何在SpringBoot中运⽤,这⾥我们来补充⼀下:
查阅SpringBoot官⽅⽂档有这么⼀段描述:
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.
官⽅介绍了两种⽅法:
1. 直接实现DisposableBean接⼝,实现destroy⽅法即可
@Slf4j
@Component
public class CustomShutdownHook implements DisposableBean {
@Override
public void destroy() throws Exception {
}
}
2. 在⽅法上使⽤@PreDestroy注解,类似@PostConstruct注解使⽤⽅法。
1. Runtime.addShutDownHook(Thread hook)
// 创建HookTest,我们通过main⽅法来模拟应⽤程序
springboot原理和生命周期public class HookTest {
public static void main(String[] args) {
/
/ 添加hook thread,重写其run⽅法
@Override
public void run() {
System.out.println("this is ");
// TODO
}
});
int i = 0;
// 这⾥会报错,我们验证写是否会执⾏hook thread
int j = 10/i;
System.out.println("j" + j);
}
}
2. Runtime.addShutDownHook(Thread hook)应⽤场景
* 程序正常退出
* 使⽤it()
* 终端使⽤Ctrl+C触发的中断
* 系统关闭
* OutofMemory宕机
* 使⽤Kill pid杀死进程(使⽤kill -9是不会被调⽤的)
3. Spring如何添加钩⼦函数
/
/ 通过这种⽅式来添加钩⼦函数
// 通过源码可以看到,
@Override
public void registerShutdownHook() {
if (this.shutdownHook == null) {
// No shutdown hook registered yet.
this.shutdownHook = new Thread() {
@Override
public void run() {
synchronized (startupShutdownMonitor) {
doClose();
}
}
};
// 也是通过这种⽅式来添加
}
}
// 重点是这个doClose()⽅法
protected void doClose() {
// Check whether an actual close attempt
if (() && this.closedpareAndSet(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 {
Close();
}
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
onClose();
// Switch to inactive.
this.active.set(false);
}
}
可以看到:doClose()⽅法会执⾏bean的destroy(),也会执⾏SmartLifeCycle的stop()⽅法,我们就可以通过重写这些⽅法来实现对象的关闭,⽣命周期的管理,实现平滑shutdown

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。