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

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方法来模拟应用程序
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的更多相关文章

  1. 如何优雅关闭 Spring Boot 应用

    ## 前言 随着线上应用逐步采用 SpringBoot 构建,SpringBoot应用实例越来多,当线上某个应用需要升级部署时,常常简单粗暴地使用 kill 命令,这种停止应用的方式会让应用将所有处理 ...

  2. 如何在 Spring Boot 优雅关闭加入一些自定义机制

    个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判.如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 i ...

  3. SpringBoot如何优雅关闭(SpringBoot2.3&Spring Boot2.2)

    SpringBoot如何优雅关闭(SpringBoot2.3&Spring Boot2.2) 优雅停止&暴力停止 暴力停止:像日常开发过程中,测试区或者本地开发时,我们并不会考虑项目关 ...

  4. Spring-IOC 在非 web 环境下优雅关闭容器

    当我们设计一个程序时,依赖了Spring容器,然而并不需要spring的web环境时(Spring web环境已经提供了优雅关闭),即程序启动只需要启动Spring ApplicationContex ...

  5. 从prototype beandefinition 谈 spring 的关闭流程和 prototype 的特性

    背景介绍: 服务端期望使用 面向对象编程, 和 spring 结合的话只能是通过 prototype 的 bean 定义,并通过 getBean 获取. 优雅停机探究: 代码说明: 1. 类关系 Si ...

  6. 优雅关闭服务下线(Jetty)

    在很多时候 kill -9 pid并不是很友好的方法,那样会将我们正在执行请求给断掉,同时eureka 中服务依旧是处于在线状态,这个时候我们可以使用官方提供的actuator来做优雅的关闭处理 - ...

  7. spring cloud: 关闭ribbon负载均衡

    spring cloud: 关闭ribbon负载均衡 1.eureka服务 2.2个user服务:7900/7901 3,movie服务 movie服务去请求 user的用户信息,而此时只想请求790 ...

  8. Socket编程中的强制关闭与优雅关闭及相关socket选项

    以下描述主要是针对windows平台下的TCP socket而言. 首先需要区分一下关闭socket和关闭TCP连接的区别,关闭TCP连接是指TCP协议层的东西,就是两个TCP端之间交换了一些协议包( ...

  9. 使用RunTime.getRunTime().addShutdownHook优雅关闭线程池

    有时候我们用到的程序不一定总是在JVM里面驻守,可能调用完就不用了,释放资源. RunTime.getRunTime().addShutdownHook的作用就是在JVM销毁前执行的一个线程.当然这个 ...

  10. 优雅关闭web服务的方式

    优雅关闭web服务 DBHelper, err = gorm.Open("mysql", "root:root@(115.159.59.129:3306)/test?ch ...

随机推荐

  1. 【pandas小技巧】--日期相关处理

    日期处理相关内容之前pandas基础系列中有一篇专门介绍过,本篇补充两个常用的技巧. 1. 多列合并为日期 当收集来的数据中,年月日等信息分散在多个列时,往往需要先合并成日期类型,然后才能做分析处理. ...

  2. JNDI注入的本地搭建和分析

    JNDI注入的本地搭建和分析   JNDI概述 JNDI(The java Naming and Directory Interface,java命名和目录接口)是一组在Java应用中访问命名和目录服 ...

  3. C++算法之旅、06 基础篇 | 第三章 图论

    常用代码模板3--搜索与图论 - AcWing DFS 尽可能往深处搜,遇到叶子节点(无路可走)回溯,恢复现场继续走 数据结构:stack 空间:需要记住路径上的点,\(O(h)\). BFS使用空间 ...

  4. Elasticsearch之常用术语

    一. 数据库和ES简单类比 关系型数据库 表(Table) 行(Row) 列(Cloumn) Schema SQL Elasticsearch 索引(Index) 文档(Document) 字段(Fi ...

  5. 【源码】Vue.js 官方脚手架 create-vue 是怎么实现的?

    Vue.js 官方脚手架 create-vue 是怎么实现的? 摘要 本文共分为四个部分,系统解析了vue.js 官方脚手架 create-vue 的实现细节. 第一部分主要是一些准备工作,如源码下载 ...

  6. 一次性全讲透GaussDB(DWS)锁的问题

    本文分享自华为云社区<GaussDB(DWS)锁问题全解>,作者: yd_211043076. 一.gaussdb有哪些锁 1.常规锁:常规锁主要用于业务访问数据库对象的加锁,保护并发操作 ...

  7. JS深入学习笔记 - 第一章.构造函数原型与原型链

    1.构造函数和原型 1.1 概述 在典型的 OOP语言中(如Java),都存在类的概念,类就是对象的模板,对象就是类的实例,但在ES6之前,JS并没有引入类的概念. 在ES6之前,对象不是基于类创建的 ...

  8. DESTOON做中英双语言(多语言)切换版本具体详解

    第一次发原创好激动,该注意点什么? 在开发过程中用户有许多要求,比如这个多语言切换就是一个需求. 首先讲解一下DESTOON(DT)后台系统如何做这个中英.甚至多语言切换的这个功能. DT本身不自带多 ...

  9. 炫酷转换:Java实现Excel转换为图片的方法

    摘要:本文由葡萄城技术团队原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 在实际开发过程中,经常会有这样的需求:将Excel表格或特定区域 ...

  10. Go 代码块与作用域,变量遮蔽问题详解

    Go 代码块与作用域详解 目录 Go 代码块与作用域详解 一.引入 二.代码块 (Block) 2.1 代码块介绍 2.2 显式代码块 2.3 隐式代码块 2.4 空代码块 2.5 支持嵌套代码块 三 ...