Spring拓展点之SmartLifecycle如何感知容器启动和关闭

          Spring为我们提供了拓展点感知容器的启动与关闭,从而使我们可以在容器启动或者关闭之时进行定制的操作。Spring提供了Lifecycle上层接口,这个接口只有两个方法start和stop两个方法,但是这个接口并不是直接提供给开发者做拓展点,而是通过SmartLifecycle为拓展点。SmartLifecycle是Lifecycle子接口,既继承了Lifecycle也继承了Phased,这个接口Phased使SmartLifecycle可以分组通知。后续介绍下SmartLifecycle怎么使用,以及它的原理。

目录

使用案例

原理机制

start()执行时机-容器refresh时实例化所有的单例对象后执行拓展点start方法

stop()执行时机-容器close时优化执行拓展点的stop方法,再清除所有单例对象

总结


使用案例

1.定义一个实现SmartLifecycle的类:

package com.cyl.lifecycle;import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;@Component
public class CylLifeCycle implements SmartLifecycle {private boolean isRunning;@Overridepublic void start() {System.out.println("容器启动");isRunning = true;}@Overridepublic void stop() {System.out.println("容器停止");isRunning = false;}@Overridepublic boolean isRunning() {return isRunning;}
}

2.启动一个容器并关闭

public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(AppConfig.class);context.refresh();System.out.println("-------------------");context.close();}

输出结果

容器启动
-------------------
容器停止

实现SmartLifecycle感知容器启动和关闭,要注意:

1.isRunning为false时,才能调用start();isRunning为true时,才能调用到stop();所以执行start()方法前要设置isRunning为false,执行完start()后设置为true。

2.实现SmartLifecycle的bean必须是单例;

分组特性一般都有多个实现SmartLifecycle类才用到,实现getPhase方法,同一个分组标记phase相同即可

//分组2
@Component
public class CylLifeCycleSecond implements SmartLifecycle {private boolean isRunning;@Overridepublic void start() {System.out.println(String.format("CylLifeCycleSecond分组%s容器启动",getPhase()));isRunning = true;}@Overridepublic void stop() {System.out.println(String.format("CylLifeCycleSecond分组%s容器启动",getPhase()));isRunning = false;}@Overridepublic boolean isRunning() {return isRunning;}@Overridepublic int getPhase() {return 2;}
}//分组1
@Component
public class CylLifeCycleFirst2 implements SmartLifecycle {private boolean isRunning;@Overridepublic void start() {System.out.println(String.format("CylLifeCycleFirst2分组%s容器启动",getPhase()));isRunning = true;}@Overridepublic void stop() {System.out.println(String.format("CylLifeCycleFirst2分组%s容器停止",getPhase()));isRunning = false;}@Overridepublic boolean isRunning() {return isRunning;}@Overridepublic int getPhase() {return 1;}
}//分组1
@Component
public class CylLifeCycleFirst implements SmartLifecycle {private boolean isRunning;@Overridepublic void start() {System.out.println(String.format("CylLifeCycleFirst分组%s容器启动",getPhase()));isRunning = true;}@Overridepublic void stop() {System.out.println(String.format("CylLifeCycleFirst分组%s容器停止",getPhase()));isRunning = false;}@Overridepublic boolean isRunning() {return isRunning;}@Overridepublic int getPhase() {return 1;}
}

最后输出结果为:

CylLifeCycleFirst分组1容器启动
CylLifeCycleFirst2分组1容器启动
CylLifeCycleSecond分组2容器启动
-------------------
CylLifeCycleSecond分组2容器启动
CylLifeCycleFirst分组1容器停止
CylLifeCycleFirst2分组1容器停止

原理机制

start()执行时机-容器refresh时实例化所有的单例对象后执行拓展点start方法

  当容器执行refresh方法的最后一步finishRefresh时,会在这一步进行获取生命周期处理器

获取所有的生命周期处理器后先根据phase分组,分组后以组维度进行start

最终会执行start,在这里会判断bean.isRunning(),若是bean.isRunning()为false时才会执行start方法

stop()执行时机-容器close时优化执行拓展点的stop方法,再清除所有单例对象

onClose方法会调用到stopBeans,也会获取所有的生命周期处理器的phase进行分组,分组后以组维度进行stop

总结

      Spring拓展点SmartLifecycle在容器启动阶段实例化所有单例对象后,获取所有实现SmartLifecycle的类,执行start方法;在容器关闭时,先获取所有实现SmartLifecycle的类,执行stop方法,最后清除所有单例对象。

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

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

相关文章

AI音乐GPT时刻来临:Suno 快速入门手册!

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…

代码块的理解

如果成员变量想要初始化的值不是一个硬编码的常量值,而是需要通过复杂的计算或读取文件、或读取运行环境信息等方式才能获取的一些值,该怎么办呢?此时,可以考虑代码块(或初始化块)。 代码块(或初始化块)的作…

前端作业之完成学校官方网页的制作

&#xff08;未使用框架&#xff0c;纯html和css制作&#xff09; 注&#xff1a;由本人技术限制&#xff0c;代码复用性极差 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>xxx大学</tit…

SpringBoot接收参数的方式

Get 请求 1.1 以方法的形参接收参数 1.这种方式一般适用参数比较少的情况 RestController RequestMapping("/user") Slf4j public class UserController {GetMapping("/detail")public Result<User> getUserDetail(String name,String phone) {log.…

zip解压异常java.lang.IllegalArgumentException: MALFORMED处理

使用hutool解压zip包时出错&#xff1a; //压缩包解压到固定目录 ZipUtil.unzip(tempZipFile,dir);在解压文件的时候报错&#xff0c;原因是压缩文件中有中文&#xff1b;导致错误&#xff0c;解决办法是设置编码&#xff1a; ZipFile tempZipFile new ZipFile(zipFile, Cha…

【Linux】详解动静态库的制作和使用动静态库在系统中的配置步骤

一、库的作用 1、提高开发效率&#xff0c;让开发者所有的函数实现不用从零开始。 2、隐藏源代码。 库其实就是所有的.o文件用特定的方式进行打包形成一个文件&#xff0c;各个.o文件包含了源代码中的机器语言指令。 二、动态库和静态库的制作和使用 2.1、静态库的制作和使用…

如何监控特权帐户,保护敏感数据

IT基础设施的增长导致员工可以访问的凭据和资源数量急剧增加。每个组织都存储关键信息&#xff0c;这些信息构成了做出关键业务决策的基石。与特权用户共享这些数据可以授予他们访问普通员工没有的凭据的权限。如果特权帐户凭证落入不法分子之手&#xff0c;它们可能被滥用&…

【重学C语言】三、C语言最简单的程序

【重学C语言】三、C语言最简单的程序 最简单的程序头文件使用尖括号 < >使用双引号 ""区别与注意事项示例 主函数认识三个错误 常量和变量常量ASCII 码表转义字符 关键字数据类型关键字存储类关键字修饰符关键字控制流程关键字函数相关关键字其他关键字 变量变…

Python中批量修改文件名,去除某些内容

环境&#xff1a;Window10 Python3.9 PyCharm(2023.1.3) -------------------------------------****************** ** *********************----------------------------------------- 这是在Python中批量将指定文件夹下相似的文件名&#xff0c;提取文件名有效信息&am…

llama.cpp运行qwen0.5B

编译llama.cp 参考 下载模型 05b模型下载 转化模型 创建虚拟环境 conda create --prefixD:\miniconda3\envs\llamacpp python3.10 conda activate D:\miniconda3\envs\llamacpp安装所需要的包 cd G:\Cpp\llama.cpp-master pip install -r requirements.txt python conver…

什么!Intel/AMD/Apple Silicon也能本地部署的Llama工具来了

主流的LLM都需要通过CUDA才能高效的运行在本地&#xff0c;但是随着Github上出现了Llama.cpp这个神器&#xff0c;一切都改变了。它通过AVX指令和MPI来实现CPU上并行计算&#xff0c;从而在本地计算机高效地运行各种主流的类Llama模型。同时它也支持metal&#xff0c;使得Apple…

go包下载时报proxyconnect tcp: dial tcp 127.0.0.1:80: connectex错误的解决方案

一大早的GoLand就开始抽风了&#xff0c;好几个文件import都红了&#xff0c;于是我正常操作点击提示的sync&#xff0c;但是却报了一堆错&#xff1a; go: downloading google.golang.org/grpc v1.61.1 go: downloading google.golang.org/genproto v0.0.0-20240228224816-df9…

LeetCode-142. 环形链表 II【哈希表 链表 双指针】

LeetCode-142. 环形链表 II【哈希表 链表 双指针】 题目描述&#xff1a;解题思路一&#xff1a;快慢指针 判断是否有环见解题思路二&#xff1a;set()解题思路三&#xff1a;0 题目描述&#xff1a; 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如…

C++重载和模板

重载与模板 函数模板可以被另一个模板或一个普通非模板函数重载。 与往常一样&#xff0c;名字相同的函数必须具有不同数量或类型的参数。 如果涉及函数模板&#xff0c;则函数匹配规则会在以下几方面受到影响&#xff1a; 对于一个调用&#xff0c;其候选函数包括所有模板…

2024第八届全国青少年无人机大赛暨中国航空航天科普展览会

2024第八届全国青少年无人机大赛暨中国航空航天科普展览会 邀请函 主办单位&#xff1a; 中国航空学会 重庆市南岸区人民政府 招商执行单位&#xff1a; 重庆港华展览有限公司 为更好的培养空航天产业人才&#xff0c;汇聚航空教育产业创新科技&#xff0c;丰富和完善航…

某音a_bogus 流程vmp分析

声明 本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 目标网站 仅研究。网站链接自己去找。 前言 这里a_bogus 又是个vmp。 还是个多层嵌套…

​LeetCode解法汇总1379. 找出克隆二叉树中的相同节点

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给你两棵二叉树&#xff0c;原始树 origi…

[Arduino学习] ESP8266读取DHT11数字温湿度传感器数据

目录 1、传感器介绍 2、接线 3、DHT.h库 1、传感器介绍 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器&#xff0c;是简单环境监测项目的理想选择。 温度分辨率为1C&#xff0c;相对湿度为1&#xff05;。温度范围在0C到50C之间&#xff0c;湿度的测…

Protobuf 二进制文件学习及解析

0. 简介 protobuf也叫protocol buffer是google 的一种数据交换的格式&#xff0c;它独立于语言&#xff0c;独立于平台。google 提供了多种语言的实现&#xff1a;java、c#、c、go 和 python&#xff0c;每一种实现都包含了相应语言的编译器以及库文件。 由于它是一种二进制的…

新人程序员必备在线工具推荐(cron、加解密、JSON、AI)

程序员必备在线工具推荐 俗话说的好&#xff0c;工欲善其事必先利其器&#xff0c;下面我就来给大家分享一下我个人常用的工具。也欢迎大家在评论区分享自己喜欢的工具。✈️ 1 在线cron表达式&#xff1a;cron 在日常开发中&#xff0c;我们难免会遇到一些定时任务的场景&…