Springboot框架扩展功能的使用
Spring Boot 提供了许多扩展点,允许开发者在应用程序的生命周期中插入自定义逻辑。这些扩展点可以帮助你更好地控制应用程序的行为,例如在启动时初始化数据、在关闭时释放资源、或者自定义配置加载逻辑。以下是 Spring Boot 中常见的扩展点:
Springboot框架扩展功能Springboot框架扩展功能
- 1. 生命周期回调
- 1.1 ApplicationRunner
- 1.2 CommandLineRunner
- 1.3 SmartLifecycle
- 2. 事件监听
- 2.1 ApplicationListener
- 2.2 常用事件
- 3. 自定义配置
- 3.1 EnvironmentPostProcessor
- 3.2 PropertySourceLoader
- 4. 自定义 Starter
- 4.1 创建自定义 Starter
- 5. 自定义健康检查
- 5.1 HealthIndicator
- 6. 自定义端点
- 6.1 Endpoint
- 7. 自定义 Bean 初始化
- 7.1 BeanPostProcessor
- 8. 自定义条件注解
- 8.1 @Conditional
- 总结
1. 生命周期回调
Spring Boot 提供了多种生命周期回调接口,可以在应用程序的不同阶段执行自定义逻辑。
1.1 ApplicationRunner
作用: 在 Spring Boot 应用启动后执行自定义逻辑。
实现方式: 实现 ApplicationRunner 接口,重写 run 方法。
示例:
@Component
public class MyApplicationRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {System.out.println("Application started with arguments: " + Arrays.toString(args.getSourceArgs()));}
}
1.2 CommandLineRunner
作用: 类似于 ApplicationRunner,但在命令行参数解析之前执行。
实现方式: 实现 CommandLineRunner 接口,重写 run 方法。
示例:
@Component
public class MyCommandLineRunner implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {System.out.println("Application started with arguments: " + Arrays.toString(args));}
}
1.3 SmartLifecycle
作用: 允许在 Spring 上下文启动和关闭时执行自定义逻辑。
实现方式: 实现 SmartLifecycle 接口,重写 start 和 stop 方法。
示例:
@Component
public class MySmartLifecycle implements SmartLifecycle {private boolean running = false;@Overridepublic void start() {System.out.println("Application is starting...");running = true;}@Overridepublic void stop() {System.out.println("Application is stopping...");running = false;}@Overridepublic boolean isRunning() {return running;}
}
2. 事件监听
Spring Boot 基于 Spring 的事件机制,允许开发者监听应用程序中的事件并执行自定义逻辑。
2.1 ApplicationListener
作用: 监听 Spring 应用事件(如上下文启动、关闭等)。
实现方式: 实现 ApplicationListener 接口,指定监听的事件类型。
示例:
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationStartedEvent> {@Overridepublic void onApplicationEvent(ApplicationStartedEvent event) {System.out.println("Application started!");}
}
2.2 常用事件
ApplicationStartingEvent: 应用启动时触发。
ApplicationStartedEvent: 应用启动完成后触发。
ApplicationReadyEvent: 应用准备就绪后触发。
ApplicationFailedEvent: 应用启动失败时触发。
3. 自定义配置
Spring Boot 允许通过扩展点自定义配置加载逻辑。
3.1 EnvironmentPostProcessor
作用: 在 Spring 环境准备完成后,对 Environment 进行自定义配置。
实现方式: 实现 EnvironmentPostProcessor 接口,并在 META-INF/spring.factories 中注册。
示例:
public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {@Overridepublic void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {environment.getPropertySources().addLast(new MyPropertySource());}
}
3.2 PropertySourceLoader
作用: 自定义属性源的加载方式(如从数据库、远程配置中心加载)。
实现方式: 实现 PropertySourceLoader 接口,并在 META-INF/spring.factories 中注册。
4. 自定义 Starter
Spring Boot 的 Starter 机制允许开发者创建自定义的自动配置模块。
4.1 创建自定义 Starter
-
创建一个自动配置类,使用 @Configuration 注解。
-
在 META-INF/spring.factories 中注册自动配置类:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.MyAutoConfiguration
打包并发布 Starter。
5. 自定义健康检查
Spring Boot 提供了健康检查机制,允许开发者自定义健康检查逻辑。
5.1 HealthIndicator
作用: 自定义健康检查逻辑。
实现方式: 实现 HealthIndicator 接口,重写 health 方法。
示例:
@Component
public class MyHealthIndicator implements HealthIndicator {@Overridepublic Health health() {// 自定义健康检查逻辑return Health.up().withDetail("status", "OK").build();}
}
6. 自定义端点
Spring Boot Actuator 允许开发者自定义监控端点。
6.1 Endpoint
作用: 创建自定义的 Actuator 端点。
实现方式: 使用 @Endpoint 注解定义端点,并使用 @ReadOperation、@WriteOperation 等注解定义操作。
示例:
@Endpoint(id = "myendpoint")
@Component
public class MyEndpoint {@ReadOperationpublic String getInfo() {return "Custom endpoint info";}
}
7. 自定义 Bean 初始化
Spring Boot 允许通过扩展点自定义 Bean 的初始化逻辑。
7.1 BeanPostProcessor
作用: 在 Bean 初始化前后执行自定义逻辑。
实现方式: 实现 BeanPostProcessor 接口,重写 postProcessBeforeInitialization 和 postProcessAfterInitialization 方法。
示例:
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("Before initialization: " + beanName);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("After initialization: " + beanName);return bean;}
}
8. 自定义条件注解
Spring Boot 允许通过条件注解控制 Bean 的加载。
8.1 @Conditional
作用: 根据条件决定是否加载 Bean。
实现方式: 自定义条件类,实现 Condition 接口,并在 @Conditional 中使用。
示例:
public class MyCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return context.getEnvironment().containsProperty("my.property");}
}@Configuration
@Conditional(MyCondition.class)
public class MyConfig {@Beanpublic MyBean myBean() {return new MyBean();}
}
总结
Spring Boot 提供了丰富的扩展点,涵盖了应用程序生命周期的各个阶段。通过合理使用这些扩展点,可以实现高度定制化的 Spring Boot 应用程序。以下是常见的扩展点分类:
生命周期回调: ApplicationRunner、CommandLineRunner、SmartLifecycle。
事件监听: ApplicationListener。
自定义配置: EnvironmentPostProcessor、PropertySourceLoader。
自定义 Starter: 自动配置类。
自定义健康检查: HealthIndicator。
自定义端点: @Endpoint。
自定义 Bean 初始化: BeanPostProcessor。
自定义条件注解: @Conditional。
根据具体需求选择合适的扩展点,可以极大地提升 Spring Boot 应用的灵活性和可维护性。
相关文章:
Springboot框架扩展功能的使用
Spring Boot 提供了许多扩展点,允许开发者在应用程序的生命周期中插入自定义逻辑。这些扩展点可以帮助你更好地控制应用程序的行为,例如在启动时初始化数据、在关闭时释放资源、或者自定义配置加载逻辑。以下是 Spring Boot 中常见的扩展点: …...
yum报错 Could not resolve host: mirrorlist.centos.org
检查dns 使用ping www.baidu.com ,如果ping不通,检查/etc/resolv.conf文件中是否有: nameserver 8.8.8.8 nameserver 8.8.4.4 替换yum源 1.备份原始的 YUM 源配置文件: sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.r…...
docker使用dockerfile打包镜像(docker如何打包)
文章目录 1. 编写 Dockerfile2. 构建 Docker 镜像3. 运行 Docker 容器4. 导出与导入镜像(可选) 1. 编写 Dockerfile Dockerfile 是一个文本文件,其中包含了一系列指令,这些指令定义了如何构建你的 Docker 镜像。下面以一个简单的…...
去中心化AGI网络架构:下一代人工智能的范式革命
文章目录 引言:当AGI遇到去中心化一、中心化AI架构的四大困境1.1 算力垄断与资源错配1.2 数据孤岛与隐私悖论1.3 模型暴政与单点故障1.4 创新抑制与价值捕获二、去中心化AGI网络的架构设计2.1 分层架构总览2.2 网络层:混合拓扑结构2.3 计算层:动态算力编排2.4 数据层:零知识…...
gitlab无法登录问题
在我第一次安装gitlab的时候发现登录页面是 正常的页面应该是 这种情况的主要原因是不是第一次登录,所以我们要找到原先的密码 解决方式: [rootgitlab ~]# vim /etc/gitlab/initial_root_password# WARNING: This value is valid only in the followin…...
单向链表在实际项目中的应用
前言 在实际项目中,单向链表经常被用来解决排队问题,因为链表允许动态地添加和移除元素,非常适合模拟队列(FIFO,先进先出)的行为。 这里的链表包含头节点,头结点的数据用来记录链表长度&#x…...
【系统架构设计师】操作系统 ③ ( 存储管理 | 页式存储弊端 - 段式存储引入 | 段式存储 | 段表 | 段表结构 | 逻辑地址 的 合法段地址判断 )
文章目录 一、页式存储弊端 - 段式存储引入1、页式存储弊端 - 内存碎片2、页式存储弊端 - 逻辑结构不匹配3、段式存储引入 二、段式存储 简介1、段式存储2、段表3、段表 结构4、段内地址 / 段内偏移5、段式存储 优缺点6、段式存储 与 页式存储 对比 三、逻辑地址 的 合法段地址…...
PDF另存为图片的一个方法
说明 有时需要把PDF的每一页另存为图片。用Devexpress可以很方便的完成这个功能。 窗体上放置一个PdfViewer。 然后循环每一页 for (int i 1; i < pdfViewer1.PageCount; i) 调用 chg_pdf_to_bmp函数获得图片并保存 chg_pdf_to_bmp中调用了PdfViewer的CreateBitmap函数…...
HTML之JavaScript运算符
HTML之JavaScript运算符 1.算术运算符 - * / %除以0,结果为Infinity取余数,如果除数为0,结果为NaN NAN:Not A Number2.复合赋值运算符 - * / %/ 除以0,结果为Infinity% 如果除数为0,结果为NaN NaN:No…...
借助 ListWise 提升推荐系统精排效能:技术、案例与优化策略
目录 一、引言二、ListWise 方法概述三、ListWise 用于精排的优势四、ListWise 样本具体的构建过程4.1 确定样本的上下文4.2 收集候选物品及相关特征4.3 确定物品的真实排序标签4.4 构建样本列表4.5 划分训练集、验证集和测试集 五、ListWise 方法案例分析六、ListWise 方法在精…...
C++中什么时候用. 什么时候用->
学了一年C今天出了一个大岔子,因为太久没有做链表类型题目了,并且STL用惯了今天遇到一题,写的时候发现完全不对劲,搞慌了,首先我们看题目 2. 两数相加 再看我第一次的解答,先不论结果对不对 错的行为有很多…...
从云原生到 AI 原生,谈谈我经历的网关发展历程和趋势
作者:谢吉宝(唐三) 编者按: 云原生 API 网关系列教程即将推出,欢迎文末查看教程内容。本文整理自阿里云智能集团资深技术专家,云原生产品线中间件负责人谢吉宝(唐三) 在云栖大会的精…...
【Python深入浅出】Python3正则表达式:开启高效字符串处理大门
目录 一、正则表达式基础入门1.1 什么是正则表达式1.2 正则表达式的语法规则1.3 特殊字符与转义 二、Python 中的 re 模块2.1 re 模块概述2.2 常用函数与方法2.2.1 re.match()2.2.2 re.search()2.2.3 re.findall()2.2.4 re.sub() 2.3 修饰符(Flags)的使用…...
Vue.js Vue CLI 安装与使用
Vue.js Vue CLI 安装与使用 今天我们来聊聊 Vue CLI 的安装与使用。对于开发 Vue 应用来说,Vue CLI 是一个非常强大的工具,它能帮助你快速创建项目脚手架、配置开发环境、自动化构建流程,从而大大提高开发效率。下面我就和大家一步一步地讲解…...
科技的尽头:在有限与永恒的夹缝中寻找文明的真谛
当人类用燧石点燃第一簇文明之火时,科技发展的齿轮便已开始转动。这个从原始工具到量子计算机的进化历程,既是人类突破生物局限的史诗,也是文明不断自我解构与重构的哲学叙事。站在人工智能与基因编辑并行的时代节点,"科技尽…...
【牛客】动态规划专题一:斐波那契数列
文章目录 DP1 斐波那契数列法1:递归法2:动态规划法3:优化空间复杂度 2.分割连接字符串3. 给定一个字符串s和一组单词dict,在s中添加空格将s变成一个句子 DP1 斐波那契数列 法1:递归 // 递归 #include <iostream>…...
java8、9新特性
JAVA8 Lambda 表达式 (parameters) -> expression 或 (parameters) ->{ statements; } 提供了一种更为简洁的语法,尤其适用于函数式接口。相比于传统的匿名内部类,Lambda 表达式使得代码更为紧凑,减少了样板代码的编写。 它允许将函…...
作业:zuoye
1.闹钟(错的) #include "widget.h" #include "ui_widget.h" #include <QMessageBox>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);// 初始化定时器objTimer new QTimer(th…...
redis底层数据结构——链表
文章目录 定义内部实现总结 定义 链表提供了高效的节点重排能力,以及顺序性的节点访间方式,并且可以通过增删节点来灵活地调整链表的长度。 作为一种常用数据结构,链表内置在很多高级的编程语言里面,因为Redis使用的C语言并没有…...
问题解决 4S 法
在深入研读《像高手一样解决问题》的第二章后,犹如打开了一扇通往高效问题解决领域的新大门,其中所阐述的问题解决 4S 法,更是给人以拨云见日之感。 一、陈述(State):明确问题本质 这是问题解决的起始点&…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
GeoServer发布PostgreSQL图层后WFS查询无主键字段
在使用 GeoServer(版本 2.22.2) 发布 PostgreSQL(PostGIS)中的表为地图服务时,常常会遇到一个小问题: WFS 查询中,主键字段(如 id)莫名其妙地消失了! 即使你在…...
RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上
一、软件介绍 文末提供程序和源码下载 RushDB 改变了您处理图形数据的方式 — 不需要 Schema,不需要复杂的查询,只需推送数据即可。 二、Key Features ✨ 主要特点 Instant Setup: Be productive in seconds, not days 即时设置 :在几秒钟…...
