Spring的SmartLifecycle可以没用过,但没听过就不好了! - 第517篇

news2024/10/6 16:16:59

历史文章(文章累计500+)

《国内最全的Spring Boot系列之一》

《国内最全的Spring Boot系列之二》

《国内最全的Spring Boot系列之三》

《国内最全的Spring Boot系列之四》

《国内最全的Spring Boot系列之五》

《国内最全的Spring Boot系列之六》

《国内最全的Spring Boot系列之七》

Spring Boot整合ElasticSearch实战 - 第511篇

Transaction rolled back because it has been marked as - 第512篇

五音不全也浪漫,521清华学霸为爱人写歌 - 第513篇

一文讲清楚SpringBoot项目打包jar后运行报错template might not exist - 第514篇

idea springboot woff/woff2/eot/ttf/svg等小图标不显示的问题 - 第515篇

Noisee AI中文站网页版 AI 音乐生成视频全新登场,快来抢先体验——国内第一个登场的中文站来袭  - 516篇

悟纤:师傅,你说有没有更优雅的方式,可以在Spring Boot的启动和关闭的时候进行一些资源的操作呐。

师傅:当然是有了,常用的 一些方式是使用@PostConstruct和@PreDestroy,但在有些场景,资源无法精准的被关停,那么这个时候可以使用SmartLifecycle。

悟纤:师傅,看着很厉害的样子呢 ,那师傅赶紧和我分享一下呗。

师傅:拿起小板凳和隔壁的小姐姐一起学习起来~

导读

最近在开发一个AI音乐项目(地址在下面)的时候,在使用队列的时候,想在程序启动和关闭的时候,对队列进行一些操作,一开始的时候@PostConstruct和@PreDestroy,但还是无法很好的进行关停,后面了解到SmartLifecycle,这个确实很好用。

项目体验地址:https://suno4.cn/#/?i=8NCBS8_WXTT

前言

SpringBoot的应用中,我们通常会利用@PostConstruct@PreDestroy注解,在Bean初始化或销毁时执行一些操作,这些操作都处于Bean声明周期的层面。

然而,在某些情况下,我们可能会遇到一些遗漏的场景,比如希望在容器本身的生命周期事件(如容器启动、停止)上执行一些操作,一个典型的例子就是在Spring Boot中启动内嵌的Web容器。这时候,该如何处理呢?

这就是我们需要利用Spring提供的另一个接口Lifecycle。接下来,我们将介绍一下Lifecycle接口以及比它更智能的SmartLifecycle

接口Lifecycle

在SpringBoot应用中如果没有调用AbstractApplicationContext#start方法,只是实现了Lifecycle接口,是不会执行Lifecycle接口中的启动方法和isRunning方法的。但在应用退出时会执行Lifecycle#isRunning方法判断该Lifecycle是否已经启动,如果返回true则调用Lifecycle#stop()停止方法。

如果使用者没有显式的调用容器的start()和stop()方法,Lifecycle的接口方法不会被执行。

而在一般的项目中,我们很少这样显式的去调用,所以就需要一个更“聪明”的类来处理,这就是SmartLifecycle

接口SmartLifecycle

可以看到SmartLifecy继承了Lifecycle,所以也就拥有了Lifecycle的能力:

start()方法:容器启动后调用

stop()方法:容器停止时调用

isRunning():检查此组件是否正在运行。

(1)只有该方法返回false时,start方法才会被执行。

(2)只有该方法返回true时,stop(Runnable callback)或stop()方法才会被执行。

SmartLifecycle继承自Lifecycle,提供了更丰富的功能:第一,start()方法无需容器显式调用就可以被执行;第二,可以控制多SmartLifecycle实例的执行顺序。

getPhase():如果有多个实现接口SmartLifecycle的类,则这些类的start的执行顺序按getPhase方法返回值从小到大执行。

例如:1比2先执行,-1比0先执行。stop方法的执行顺序则相反,getPhase返回值较大类的stop方法先被调用,小的后被调用。

如何使用呢?很简单

import org.springframework.context.SmartLifecycle;import org.springframework.stereotype.Component;@Componentpublic class MySmartLifecycle implements SmartLifecycle {    private volatile boolean running = false;    /**     * 如果该`Lifecycle`类所在的上下文在调用`refresh`时,希望能够自己自动进行回调,则返回`true`,     * false的值表明组件打算通过显式的start()调用来启动,类似于普通的Lifecycle实现。     * 默认就是true,所以可以不用重写此方法。     *///    @Override//    public boolean isAutoStartup() {//        return true;//    }    /**     * 1. 主要在该方法中启动任务或者其他异步服务,比如开启MQ接收消息<br/>     * 2. 当上下文被刷新(所有对象已被实例化和初始化之后)时,将调用该方法,     * 默认生命周期处理器将检查每个SmartLifecycle对象的isAutoStartup()方法返回的布尔值。     * 如果为“true”,则该方法会被调用,而不是等待显式调用自己的start()方法。     */    @Override    public void start() {        System.out.println("MySmartLifecycle容器启动完成 ...");        running = true;    }    /**     * SmartLifecycle子类的才有的方法,当isRunning方法返回true时,该方法才会被调用。     * 很多框架中的源码中,都会把真正逻辑写在stop()方法内。     * 比如quartz和Redis的spring支持包。     */    @Override    public void stop(Runnable callback) {        System.out.println("MySmartLifecycle容器停止,执行回调函数");        stop();        // 如果你让isRunning返回true,需要执行stop这个方法,那么就不要忘记调用callback.run()。        // 否则在程序退出时,Spring的DefaultLifecycleProcessor会认为这个MySmartLifecycle没有stop完成,程序会一直卡着结束不了,等待一定时间(默认超时时间30秒)后才会自动结束。        callback.run();    }    /**     * 接口Lifecycle子类的方法,只有非SmartLifecycle的子类才会执行该方法。<br/>     * 1. 该方法只对直接实现接口Lifecycle的类才起作用,对实现SmartLifecycle接口的类无效。<br/>     * 2. 方法stop()和方法stop(Runnable callback)的区别只在于,后者是SmartLifecycle子类的专属。     */    @Override    public void stop() {        System.out.println("MySmartLifecycle容器停止 ...");        running = false;    }    /**     * 1. 只有该方法返回false时,start方法才会被执行。<br/>     * 2. 只有该方法返回true时,stop(Runnable callback)或stop()方法才会被执行。     */    @Override    public boolean isRunning() {        System.out.println("MySmartLifecycle检查运行状态 ...");        return running;    }    /**     * 如果有多个实现接口SmartLifecycle的类,则这些类的start的执行顺序按getPhase方法返回值从小到大执行。<br/>     * 例如:1比2先执行,-1比0先执行。stop方法的执行顺序则相反,getPhase返回值较大类的stop方法先被调用,小的后被调用。     *     */    @Override    public int getPhase() {        return 0;    }}

启动的日志打印:

MySmartLifecycle检查运行状态 ...

MySmartLifecycle容器启动完成 ...

关闭的日志打印:

MySmartLifecycle检查运行状态 ...

MySmartLifecycle容器停止,执行回调函数

MySmartLifecycle容器停止 ...

SmartLifecycle使用场景

(1)异步初始化或销毁操作: SmartLifecycle接口允许在容器启动或关闭过程中执行异步操作。这对于需要在应用程序启动或关闭时执行长时间运行的任务或资源清理操作非常有用。

(2)有序启动和关闭: SmartLifecycle可以指定组件的启动和关闭顺序,确保在启动或关闭过程中其他组件已经准备好或者已经完成。当你的组件在启动的时候,有依赖关系的话,那么就可以SmartLifecycle来进行控制组件的启动顺序。

(3)动态决定启动和关闭: SmartLifecycle接口中的方法能够让组件动态地决定何时启动或关闭。这使得在特定条件满足时才启动或关闭组件成为可能,从而提高了系统的灵活性和可控性。

(4)状态管理: SmartLifecycle接口提供了方法来查询组件的当前状态,例如是否已经启动或停止。这对于在应用程序的其他部分中根据组件状态做出决策或执行特定的逻辑非常有用。

(5)资源监控器的启动和停止: 如果应用程序中存在资源监控器,可以使用SmartLifecycle接口来启动和停止这些监控器。在应用程序启动时,监控器可以开始监控资源的使用情况。在应用程序关闭时,可以停止监控器并释放资源。

以下是一些具体的SmartLifecycle接口的应用场景:

(1)数据库连接池的管理: 在应用程序启动时,可以利用SmartLifecycle接口来初始化数据库连接池。在应用程序关闭时,可以利用SmartLifecycle接口来优雅地关闭数据库连接池,确保所有数据库连接都已释放。

(2)缓存的初始化和销毁: 在应用程序启动时,可以使用SmartLifecycle接口来初始化缓存并加载数据。在应用程序关闭时,可以使用SmartLifecycle接口来优雅地销毁缓存并释放资源。

(3)定时任务的管理: 如果应用程序中存在定时任务,可以使用SmartLifecycle接口来启动和关闭这些定时任务。在应用程序启动时,定时任务可以注册并开始执行。在应用程序关闭时,可以优雅地停止定时任务的执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1832865.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML基础结构入门

HTML&#xff08;超文本标记语言&#xff09;是构建网页的基础语言。它用于描述网页的结构和内容。让我们从最基本的HTML文档开始。 HTML基础结构 一个基本的HTML文档结构如下&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta …

PMP证书有何用?

PMP证书有何用&#xff1f; PMP项目管理专业人士资格认证证书对从事或希望从事项目管理工作的人员有重要意义&#xff0c;具体体现在以下几个方面&#xff1a; 1. 提供职业机会&#xff1a; PMP是项目管理领域的国际认可标准&#xff0c;拥有该证书的人在求职时具备了更强的…

python-docx-template 的 Replace docx pictures 占位图片名称从哪来?

python-docx-template 的 Replace docx pictures 占位图片名称从哪来&#xff1f; 在 Word 中看占位图片名称用代码输出输出结果找对应图片 使用 replace_pic参考资料 在 Word 中看占位图片名称 右键图片 》查看可选文字 用代码输出 from docxtpl import DocxTemplate# 初始化…

【proteus仿真】基于51单片机的电压检测系统

【proteus仿真】基于51单片机的电压检测系统 资料下载地址&#xff1a;关注公众号 小邵爱电子 获取 1.前言 使用51单片机和ADC模块设计一个数字电压表&#xff0c;将模拟信号0~5V之间的电压转换为数字量信号&#xff0c;并通过LED实时显示电压数据 、 2.仿真原理图 3.硬件…

python安装目录文件说明----Dlls文件夹

在Python的安装目录下&#xff0c;通常会有一个DLLs文件夹&#xff0c;它是Python标准库的一部分。这个文件夹包含了一些动态链接库&#xff08;Dynamic Link Libraries&#xff0c;DLL&#xff09;&#xff0c;这些库提供了Python解释器和标准库的一些关键功能。以下是对这个文…

Linux(Centos7)OpenSSH漏洞修复,升级最新openssh-9.7p1

OpenSSH更新 一、OpenSSH漏洞二、安装zlib三、安装OpenSSL四、安装OpenSSH 一、OpenSSH漏洞 服务器被扫描出了漏洞需要修复&#xff0c;准备升级为最新openssh服务 1. 使用ssh -v查看本机ssh服务版本号 ssh -V虚拟机为OpenSSH7.4p1&#xff0c;现在准备升级为OpenSSH9.7p1…

Windows 与 Java 环境下的 Redis 利用分析

1 前言 在最近的一次攻防演练中&#xff0c;遇到了两个未授权访问的 Redis 实例。起初以为可以直接利用&#xff0c;但后来发现竟然是Windows Java (Tomcat)。因为网上没有看到相关的利用文章&#xff0c;所以在经过摸索&#xff0c;成功解决之后决定简单写一写。 本文介绍了…

洗地机性价比高的是哪一款?行内人告诉你

在浏览前&#xff0c;希望您轻触屏幕上方的“关注”按钮&#xff0c;让我后续为您带来更多实用且精彩的内容&#xff0c;感谢您的支持&#xff01; 洗地机作为现在的流行清洁工具&#xff0c;它的魅力之处在于&#xff1a;性价比极高&#xff0c;大多数家庭无需花费过多就能把…

java的Filter(过滤器),Interceptor(拦截器) 和 Aspect(切面)

文章目录 前言一、过滤器 (Filter) 基本用法二、拦截器 (Interceptor) 基本用法三、Aspect(切面)的基本用法总结 前言 Filter 是servlet层面的&#xff0c;由Servlet容器(如Tomcat)支持&#xff0c;只能在web程序中使用&#xff0c;实现了javax.servlet.Filter接口 Intercept…

2024北京智源大会

北京智源大会是年度国际性人工智能高端学术交流的盛会&#xff0c;定位于内行的AI盛会。智源大会紧密围绕当前人工智能学术领域迫切需要解决的问题&#xff0c;以及产业落地过程中存在的诸多挑战&#xff0c;开展深入探讨。智源研究院是2018年11月份成立的一家人工智能领域的新…

直播美颜SDK技术指南:实现实时美颜效果的算法方案

本篇文章&#xff0c;小编将探讨直播美颜SDK的技术实现和算法方案。 一、美颜技术概述 美颜技术通过一系列图像处理算法&#xff0c;实时美颜效果可以在视频直播过程中实时呈现&#xff0c;提升用户的直播体验。为了实现这些效果&#xff0c;需要结合图像处理和计算机视觉技术…

“奇点”临近,产业应用与人工智能怎样“共同进化”

以下文章来源&#xff1a;新华日报 眼下&#xff0c;以大模型为核心的人工智能技术呈现颠覆性突破。年初&#xff0c;OpenAI公司发布旗下的文生视频大模型Sora&#xff0c;距去年ChatGPT的横空出世&#xff0c;也仅仅过去一年。 “当前&#xff0c;人工智能迈向通用智能‘奇点’…

Hue Hadoop 图形化用户界面 BYD

软件简介 Hue 是运营和开发 Hadoop 应用的图形化用户界面。Hue 程序被整合到一个类似桌面的环境&#xff0c;以 web 程序的形式发布&#xff0c;对于单独的用户来说不需要额外的安装。

綦江蜘蛛池四川官网下载

baidu搜索&#xff1a;如何联系八爪鱼SEO? baidu搜索&#xff1a;如何联系八爪鱼SEO? baidu搜索&#xff1a;如何联系八爪鱼SEO? CCSEO蜘蛛统计开发思路一般包括以下几个步骤: 定义需求:明确统计蜘蛛访问数据的目标和要求,例如需要获取哪些信息,统计的精度和频率等。 确定数…

springboot小型超市商品展销系统-计算机毕业设计源码01635

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…

thinkphp5使用模型删除与复杂查询EXP

模型删除 应用软删除 表中需要有字段&#xff0c;deletetime 模型中使用下面方法 use SoftDelete;protected $deleteTime delete_time;真实删除 // 软删除 User::destroy(1); // 真实删除 User::destroy(1,true); $user User::get(1); // 软删除 $user->delete(); // 真…

Python批量保存Excel文件中的图表为图片

Excel工作簿作为一款功能强大的数据处理与分析工具&#xff0c;被广泛应用于各种领域&#xff0c;不仅能够方便地组织和计算数据&#xff0c;还支持用户创建丰富多彩的图表&#xff0c;直观展示数据背后的洞察与趋势。然而&#xff0c;在报告编制、网页内容制作或分享数据分析成…

SFTP共享配置

SFTP一般指SSH文件传输协议&#xff0c;在计算机领域&#xff0c;SSH文件传输协议&#xff08;英语&#xff1a;SSH File Transfer Protocol&#xff0c;也称Secret File Transfer Protocol&#xff0c;中文&#xff1a;安全文件传送协议&#xff0c;英文&#xff1a;Secure FT…

FFmpeg中内存分配和释放相关的源码:av_malloc函数、av_mallocz函数、av_free函数和av_freep函数分析

一、av_malloc函数分析 &#xff08;一&#xff09;av_malloc函数的声明 av_malloc函数的声明放在在FFmpeg源码&#xff08;本文演示用的FFmpeg源码版本为5.0.3&#xff0c;该ffmpeg在CentOS 7.5上通过10.2.1版本的gcc编译&#xff09;的头文件libavutil/mem.h中&#xff1a;…

nvm 报错https://npm.taobao.org/mirrors/node/index.json 淘宝镜像更换

文章目录 一、问题背景二、解决问题1. 获取配置文件的位置2. 修改配置文件中的镜像源配置3. 修改 npm 镜像源 一、问题背景 使用nvm的时候报错: Could not retrieve https://npm.taobao.org/mirrors/node/index.json. 由于淘宝的镜像域名更换&#xff0c;npm.taobao.org 域名…