当前位置: 首页 > news >正文

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

  1. 创建一个自动配置类,使用 @Configuration 注解。

  2. 在 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 提供了许多扩展点&#xff0c;允许开发者在应用程序的生命周期中插入自定义逻辑。这些扩展点可以帮助你更好地控制应用程序的行为&#xff0c;例如在启动时初始化数据、在关闭时释放资源、或者自定义配置加载逻辑。以下是 Spring Boot 中常见的扩展点&#xff1a; …...

yum报错 Could not resolve host: mirrorlist.centos.org

检查dns 使用ping www.baidu.com &#xff0c;如果ping不通&#xff0c;检查/etc/resolv.conf文件中是否有&#xff1a; nameserver 8.8.8.8 nameserver 8.8.4.4 替换yum源 1.备份原始的 YUM 源配置文件&#xff1a; sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.r…...

docker使用dockerfile打包镜像(docker如何打包)

文章目录 1. 编写 Dockerfile2. 构建 Docker 镜像3. 运行 Docker 容器4. 导出与导入镜像&#xff08;可选&#xff09; 1. 编写 Dockerfile Dockerfile 是一个文本文件&#xff0c;其中包含了一系列指令&#xff0c;这些指令定义了如何构建你的 Docker 镜像。下面以一个简单的…...

去中心化AGI网络架构:下一代人工智能的范式革命

文章目录 引言:当AGI遇到去中心化一、中心化AI架构的四大困境1.1 算力垄断与资源错配1.2 数据孤岛与隐私悖论1.3 模型暴政与单点故障1.4 创新抑制与价值捕获二、去中心化AGI网络的架构设计2.1 分层架构总览2.2 网络层:混合拓扑结构2.3 计算层:动态算力编排2.4 数据层:零知识…...

gitlab无法登录问题

在我第一次安装gitlab的时候发现登录页面是 正常的页面应该是 这种情况的主要原因是不是第一次登录&#xff0c;所以我们要找到原先的密码 解决方式&#xff1a; [rootgitlab ~]# vim /etc/gitlab/initial_root_password# WARNING: This value is valid only in the followin…...

单向链表在实际项目中的应用

前言 在实际项目中&#xff0c;单向链表经常被用来解决排队问题&#xff0c;因为链表允许动态地添加和移除元素&#xff0c;非常适合模拟队列&#xff08;FIFO&#xff0c;先进先出&#xff09;的行为。 这里的链表包含头节点&#xff0c;头结点的数据用来记录链表长度&#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&#xff0c;结果为Infinity取余数&#xff0c;如果除数为0&#xff0c;结果为NaN NAN:Not A Number2.复合赋值运算符 - * / %/ 除以0&#xff0c;结果为Infinity% 如果除数为0&#xff0c;结果为NaN NaN:No…...

借助 ListWise 提升推荐系统精排效能:技术、案例与优化策略

目录 一、引言二、ListWise 方法概述三、ListWise 用于精排的优势四、ListWise 样本具体的构建过程4.1 确定样本的上下文4.2 收集候选物品及相关特征4.3 确定物品的真实排序标签4.4 构建样本列表4.5 划分训练集、验证集和测试集 五、ListWise 方法案例分析六、ListWise 方法在精…...

C++中什么时候用. 什么时候用->

学了一年C今天出了一个大岔子&#xff0c;因为太久没有做链表类型题目了&#xff0c;并且STL用惯了今天遇到一题&#xff0c;写的时候发现完全不对劲&#xff0c;搞慌了&#xff0c;首先我们看题目 2. 两数相加 再看我第一次的解答&#xff0c;先不论结果对不对 错的行为有很多…...

从云原生到 AI 原生,谈谈我经历的网关发展历程和趋势

作者&#xff1a;谢吉宝&#xff08;唐三&#xff09; 编者按&#xff1a; 云原生 API 网关系列教程即将推出&#xff0c;欢迎文末查看教程内容。本文整理自阿里云智能集团资深技术专家&#xff0c;云原生产品线中间件负责人谢吉宝&#xff08;唐三&#xff09; 在云栖大会的精…...

【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 修饰符&#xff08;Flags&#xff09;的使用…...

Vue.js Vue CLI 安装与使用

Vue.js Vue CLI 安装与使用 今天我们来聊聊 Vue CLI 的安装与使用。对于开发 Vue 应用来说&#xff0c;Vue CLI 是一个非常强大的工具&#xff0c;它能帮助你快速创建项目脚手架、配置开发环境、自动化构建流程&#xff0c;从而大大提高开发效率。下面我就和大家一步一步地讲解…...

科技的尽头:在有限与永恒的夹缝中寻找文明的真谛

当人类用燧石点燃第一簇文明之火时&#xff0c;科技发展的齿轮便已开始转动。这个从原始工具到量子计算机的进化历程&#xff0c;既是人类突破生物局限的史诗&#xff0c;也是文明不断自我解构与重构的哲学叙事。站在人工智能与基因编辑并行的时代节点&#xff0c;"科技尽…...

【牛客】动态规划专题一:斐波那契数列

文章目录 DP1 斐波那契数列法1&#xff1a;递归法2&#xff1a;动态规划法3&#xff1a;优化空间复杂度 2.分割连接字符串3. 给定一个字符串s和一组单词dict&#xff0c;在s中添加空格将s变成一个句子 DP1 斐波那契数列 法1&#xff1a;递归 // 递归 #include <iostream>…...

java8、9新特性

JAVA8 Lambda 表达式 (parameters) -> expression 或 (parameters) ->{ statements; } 提供了一种更为简洁的语法&#xff0c;尤其适用于函数式接口。相比于传统的匿名内部类&#xff0c;Lambda 表达式使得代码更为紧凑&#xff0c;减少了样板代码的编写。 它允许将函…...

作业:zuoye

1.闹钟&#xff08;错的&#xff09; #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底层数据结构——链表

文章目录 定义内部实现总结 定义 链表提供了高效的节点重排能力&#xff0c;以及顺序性的节点访间方式&#xff0c;并且可以通过增删节点来灵活地调整链表的长度。 作为一种常用数据结构&#xff0c;链表内置在很多高级的编程语言里面&#xff0c;因为Redis使用的C语言并没有…...

问题解决 4S 法

在深入研读《像高手一样解决问题》的第二章后&#xff0c;犹如打开了一扇通往高效问题解决领域的新大门&#xff0c;其中所阐述的问题解决 4S 法&#xff0c;更是给人以拨云见日之感。 一、陈述&#xff08;State&#xff09;&#xff1a;明确问题本质 这是问题解决的起始点&…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

视觉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&#xff08;版本 2.22.2&#xff09; 发布 PostgreSQL&#xff08;PostGIS&#xff09;中的表为地图服务时&#xff0c;常常会遇到一个小问题&#xff1a; WFS 查询中&#xff0c;主键字段&#xff08;如 id&#xff09;莫名其妙地消失了&#xff01; 即使你在…...

RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上

一、软件介绍 文末提供程序和源码下载 RushDB 改变了您处理图形数据的方式 — 不需要 Schema&#xff0c;不需要复杂的查询&#xff0c;只需推送数据即可。 二、Key Features ✨ 主要特点 Instant Setup: Be productive in seconds, not days 即时设置 &#xff1a;在几秒钟…...