Spring优雅关闭之:ShutDownHook
转载自:https://blog.csdn.net/qq_26323323/article/details/89814410
2020/02/26重新编辑一下
前面介绍ShutDownHook的基本使用方法,但是没有清楚的表述如何在SpringBoot中运用,这里我们来补充一下:
查阅SpringBoot官方文档有这么一段描述:
1.10. Application Exit
Each
SpringApplicationregisters a shutdown hook with the JVM to ensure that theApplicationContextcloses gracefully on exit. All the standard Spring lifecycle callbacks (such as theDisposableBeaninterface or the@PreDestroyannotation) 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方法来模拟应用程序
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
Spring优雅关闭之:ShutDownHook的更多相关文章
- 如何优雅关闭 Spring Boot 应用
## 前言 随着线上应用逐步采用 SpringBoot 构建,SpringBoot应用实例越来多,当线上某个应用需要升级部署时,常常简单粗暴地使用 kill 命令,这种停止应用的方式会让应用将所有处理 ...
- 如何在 Spring Boot 优雅关闭加入一些自定义机制
个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判.如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 i ...
- SpringBoot如何优雅关闭(SpringBoot2.3&Spring Boot2.2)
SpringBoot如何优雅关闭(SpringBoot2.3&Spring Boot2.2) 优雅停止&暴力停止 暴力停止:像日常开发过程中,测试区或者本地开发时,我们并不会考虑项目关 ...
- Spring-IOC 在非 web 环境下优雅关闭容器
当我们设计一个程序时,依赖了Spring容器,然而并不需要spring的web环境时(Spring web环境已经提供了优雅关闭),即程序启动只需要启动Spring ApplicationContex ...
- 从prototype beandefinition 谈 spring 的关闭流程和 prototype 的特性
背景介绍: 服务端期望使用 面向对象编程, 和 spring 结合的话只能是通过 prototype 的 bean 定义,并通过 getBean 获取. 优雅停机探究: 代码说明: 1. 类关系 Si ...
- 优雅关闭服务下线(Jetty)
在很多时候 kill -9 pid并不是很友好的方法,那样会将我们正在执行请求给断掉,同时eureka 中服务依旧是处于在线状态,这个时候我们可以使用官方提供的actuator来做优雅的关闭处理 - ...
- spring cloud: 关闭ribbon负载均衡
spring cloud: 关闭ribbon负载均衡 1.eureka服务 2.2个user服务:7900/7901 3,movie服务 movie服务去请求 user的用户信息,而此时只想请求790 ...
- Socket编程中的强制关闭与优雅关闭及相关socket选项
以下描述主要是针对windows平台下的TCP socket而言. 首先需要区分一下关闭socket和关闭TCP连接的区别,关闭TCP连接是指TCP协议层的东西,就是两个TCP端之间交换了一些协议包( ...
- 使用RunTime.getRunTime().addShutdownHook优雅关闭线程池
有时候我们用到的程序不一定总是在JVM里面驻守,可能调用完就不用了,释放资源. RunTime.getRunTime().addShutdownHook的作用就是在JVM销毁前执行的一个线程.当然这个 ...
- 优雅关闭web服务的方式
优雅关闭web服务 DBHelper, err = gorm.Open("mysql", "root:root@(115.159.59.129:3306)/test?ch ...
随机推荐
- 后缀数组C++详解
后缀定义 "后缀i"代表以第i个字符开头的后缀,存储是用i代表字符串s的后缀s[i...n] 后缀数组是什么? 后缀数组(Suffix Array)主要关系到两个数组:sa 和 r ...
- C#利用Refit实现JWT自动续期
前言 笔者之前开发过一套C/S架构的桌面应用,采用了JWT作为用户的登录认证和授权.遇到的唯一问题就是JWT过期了该怎么办?设想当一个用户正在进行业务操作,突然因为Token过期失效,莫名其妙地跳转到 ...
- centos7.X安装mysql5.7 – 东凭渭水流
1.下载mysql5.7 可以使用windows下载好后上传至Linux.网络条件好的推荐使用 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/m ...
- do_fork(一)
fork 是linux创建进程的系统调用,相关的函数(不只是系统调用)还有 vfork,clone,sys_frok等.这些函数会整理不同参数,再调用到 do_fork 中. 本篇文章主要介绍do_f ...
- 循环神经网络RNN完全解析:从基础理论到PyTorch实战
在本文中,我们深入探讨了循环神经网络(RNN)及其高级变体,包括长短时记忆网络(LSTM).门控循环单元(GRU)和双向循环神经网络(Bi-RNN).文章详细介绍了RNN的基本概念.工作原理和应用场景 ...
- Linux下MySQL备份指定数据库命令
比如我们要备份mysql中已经存在的名为linux的数据库,要用到命令mysqldump 命令格式如下: [root@linuxsir01 root]# mysqldump -u root -p li ...
- WebAPI接口文档快速编写
近期项目使用了WebAPI,需要先给出接口文档,本着能省事就省事的原则,自然最好是能找到自动生成文档的方式. 一.使用Apifox,官网写着这是个API一体化协作平台,说白了,对于我来说,这就是个测试 ...
- OPPO主题组件开发 - 组件内容自适应
OPPO桌面有 3*5.3*6.4*5.4*6.5*5.5*6 等布局,随着布局不同,组件大小也会发生改变:不同型号手机分辨率不同,组件大小也不一致.这就要求组件内容做到自适应. 说明 OPPO主题组 ...
- Qt信号槽与事件循环学习笔记
事件与事件循环 信号槽机制 事件与事件循环 在Qt中,事件(event)被封装为QEvent类/子类对象,用来表示应用内部或外部发生的各种事情.事件可以被任何QObject子类的对象接收并处理. 根据 ...
- client-go实战之九:手写一个kubernetes的controller
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<client-go实战> ...