重学SpringBoot3-SpringApplicationRunListener

news/2024/9/18 16:06:51/ 标签: spring boot, java

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》
期待您的点赞👍收藏⭐评论✍

重学SpringBoot3-SpringApplicationRunListener

  • 1. 基本作用
  • 2. 如何实现
    • 2.1. 创建SpringApplicationRunListener
    • 2.2. 注册SpringApplicationRunListener
    • 2.3. 完整示例
  • 3. 适用场景
  • 4. 总结

SpringApplicationRunListener 是 Spring Boot 框架中的一个接口,主要用于监听 Spring Boot 应用启动过程中的不同阶段。通过实现这个接口,开发者可以在应用启动的过程中插入自定义的逻辑,例如在启动前进行某些预处理、修改应用上下文,甚至在启动失败时做出相应的处理。

在 Spring Boot 3 中,SpringApplicationRunListener 保持了其核心功能,并且随着 Spring 框架的进化,提供了一些更灵活的应用配置和启动定制化支持。

1. 基本作用

SpringApplicationRunListener 作为一个监听器接口,提供了多个钩子方法来捕捉应用启动的各个阶段。Spring Boot 应用启动过程中大致包含以下几个步骤:

  1. 准备环境(EnvironmentPrepared):在读取应用程序配置、解析命令行参数后,准备运行环境。
  2. 准备上下文(ContextPrepared):在应用上下文被创建并准备好但尚未刷新时。
  3. 上下文加载完成(ContextLoaded):在应用上下文加载完成但还未启动时。
  4. 上下文启动(Started):应用上下文刷新并启动。
  5. 运行完成(Running/Ready):整个应用完全启动并准备处理请求。
  6. 启动失败(Failed):应用在启动过程中发生错误或异常。

通过实现 SpringApplicationRunListener,可以在这些关键步骤之间插入自定义逻辑,以扩展和控制应用的启动行为。

2. 如何实现

要自定义 SpringApplicationRunListener,需要:

  1. 实现接口:创建一个类实现 SpringApplicationRunListener 接口。
  2. 注册监听器:在 META-INF/spring.factories 文件中注册自定义的监听器类。

2.1. 创建SpringApplicationRunListener

首先,创建一个类并实现 SpringApplicationRunListener 接口。

SpringBoot2.6以上版本

java">package com.coderjia.boot.confi;import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;import java.time.Duration;/*** @author CoderJia* @create 2024/09/13 15:41* @Description**/
public class CustomSpringApplicationRunListener implements SpringApplicationRunListener {public CustomSpringApplicationRunListener(SpringApplication application, String[] args) {// 必须定义这个构造方法,以便 Spring 能正确初始化这个监听器}@Overridepublic void starting(ConfigurableBootstrapContext bootstrapContext) {System.out.println("应用正在启动:starting()");}@Overridepublic void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {System.out.println("环境已经准备好:environmentPrepared()");}@Overridepublic void contextPrepared(ConfigurableApplicationContext context) {System.out.println("上下文已准备:contextPrepared()");}@Overridepublic void contextLoaded(ConfigurableApplicationContext context) {System.out.println("上下文已加载:contextLoaded()");}@Overridepublic void started(ConfigurableApplicationContext context, Duration timeTaken) {System.out.println("应用已启动!启动耗时:" + timeTaken.toMillis() + " 毫秒");}@Overridepublic void ready(ConfigurableApplicationContext context, Duration timeTaken) {System.out.println("应用已准备就绪!启动耗时:" + timeTaken.toMillis() + " 毫秒");}@Overridepublic void failed(ConfigurableApplicationContext context, Throwable exception) {System.out.println("应用启动失败:failed()");}
}

每个方法代表应用启动的一个关键阶段,开发者可以在这些方法中插入自定义逻辑,如日志记录、性能监控或额外的资源加载。

SpringBoot2.6之前版本

SpringBoot2.6以上版本主要是用running 方法被替换为 ready 方法,started 方法现在也接收一个额外的 Duration timeTaken 参数。

为什么替换 runningready

Spring Boot 团队在 2.6.0 版本中做出这一修改的目的是为了更加精确地表示应用启动完成的状态。running 方法的名称虽然也表示应用已经启动,但它并没有表达出应用已经完全准备好处理外部请求的意思。相反,ready 方法名称更明确,表示应用已经达到可用状态。另外,Duration 参数为开发者提供了额外的信息,能够监控启动时间。这对生产环境下的性能调优和监控非常有帮助。

started和ready的区别

在 Spring Boot 的应用生命周期中,started 方法表示应用上下文已经刷新并完全启动,此时 Bean 已经加载完成,ApplicationContext 已经初始化和准备好。和 ready 方法的区别是,started 标志着应用在完成上下文刷新之后,还没有完全准备好处理外部请求,而 ready 是表示应用进入可以处理请求的状态。通过添加 Duration timeTaken 参数,开发者可以记录应用从启动到上下文准备完成的时间,这对于分析应用启动阶段的性能非常有帮助。

2.2. 注册SpringApplicationRunListener

要使 Spring Boot 能够发现并使用自定义的监听器,需要在 META-INF/spring.factories 文件中进行注册。确保该文件位于 resources 目录下,内容如下:

org.springframework.boot.SpringApplicationRunListener=\
com.coderjia.boot.confi.CustomSpringApplicationRunListener

spring.factories配置

这个配置会告诉 Spring Boot 在启动时加载并使用自定义的 SpringApplicationRunListener 实现。

2.3. 完整示例

新建一个 Spring Boot 项目,在项目中,我们希望在启动的每个阶段输出日志,确保启动过程中的每个步骤都清晰可见。以下是一个完整的代码示例:

启动 Spring Boot 应用时,就会在控制台中看到每个启动阶段的日志输出。

演示

3. 适用场景

SpringApplicationRunListener 的使用场景包括但不限于:

  • 启动日志记录:可以精确记录应用的启动过程,便于后续的性能分析和调优。
  • 环境变量配置:在 environmentPrepared 阶段,可以动态调整环境变量的值。
  • 启动故障处理:在 failed 方法中处理启动失败后的逻辑,比如发送通知或日志存储。
  • 条件化启动逻辑:可以根据不同的条件,在启动过程中启用或禁用特定的功能。

4. 总结

SpringApplicationRunListener 提供了一个强大的机制,用于在 Spring Boot 应用启动的多个关键阶段插入自定义逻辑。在 Spring Boot 3 中,这个接口依旧是扩展应用启动流程的有效方式。通过合理使用 SpringApplicationRunListener,开发者可以更加灵活地控制应用的启动行为,并为复杂的启动场景提供解决方案。希望这篇文章能够帮助你更好地理解和使用 SpringApplicationRunListener


http://www.ppmy.cn/news/1525957.html

相关文章

k8s(kubernetes)的PV / PVC / StorageClass(理论+实践)

NFS总是不支持PVC扩容 先来个一句话总结:PV、PVC是K8S用来做存储管理的资源对象,它们让存储资源的使用变得可控,从而保障系统的稳定性、可靠性。StorageClass则是为了减少人工的工作量而去自动化创建PV的组件。所有Pod使用存储只有一个原则&…

深入了解HarmonyOS(鸿蒙操作系统)

深入了解HarmonyOS(鸿蒙操作系统):全场景智慧生活的核心 引言 随着物联网和人工智能的快速发展,传统的操作系统已难以满足多设备、多场景的智能互联需求。为此,华为于2019年正式发布了自主研发的操作系统——Harmony…

【LeetCode 算法笔记】155. 最小栈

目录 问题描述单个栈实现双栈实现不开辟额外空间 问题描述 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。 void push(int val) 将元素val推入堆栈。 void pop()…

Github 2024-09-12 Go开源项目日报Top10

根据Github Trendings的统计,今日(2024-09-12统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Go项目10C项目1Terraform:基础设施即代码的开源工具 创建周期:3626 天开发语言:Go协议类型:OtherStar数量:40393 个Fork数量:9397 次关注…

ios xib 子控件约束置灰不能添加约束

添加约束时发现置灰不可点的问题 layout切换为inferred,就可以添加约束了

项目:完成局域网CS模型,局域网内一个服务器,多个客户端连接一个服务器,完成局域网聊天。

server.c #include<myhead.h> #define SERPORT 8888 #define SERIP "192.168.0.169" #define BACKLOG 20 typedef struct { int newfd; // 存储新文件描述符 struct sockaddr_in cin; // 存储客户端信息 } HMY; void *fun1(void *sss) { HMY *msg …

[译] 当Go程序结束时会发生什么

本篇内容是根据2021年2月份When Go programs end音频录制内容的整理与翻译,两位主持人邀请Go团队的Michael Knyszek,讨论了当Go程序结束时会发生什么 过程中为符合中文惯用表达有适当删改, 版权归原作者所有. Mat Ryer: 大家好&#xff0c;欢迎收听 Go Time。我是 Mat Ryer。今…

Mybatis-plus进阶篇(二)

文章目录 一.条件构造器方法1.eq使用范围方法签名参数说明示例 2.ne使用范围方法签名参数说明示例 3.gt使用范围方法签名参数说明示例 4.ge使用范围方法签名参数说明示例 5.lt使用范围方法签名参数说明示例 6.le使用范围方法签名参数说明示例 7.between使用范围方法签名参数说明…

18068 选择排序

### 思路 1. **初始化**&#xff1a;定义变量i, j, k和临时变量tmp。 2. **外层循环**&#xff1a;遍历数组的每个元素&#xff0c;i从0到n-2。 3. **内层循环**&#xff1a;从i1到n-1&#xff0c;找到最小元素的索引k。 4. **交换**&#xff1a;将最小元素与当前元素交换。 #…

矩阵直播换IP:如何使用代理IP提升直播效果

在直播行业中&#xff0c;稳定的网络连接和高质量的直播效果至关重要。然而&#xff0c;随着观众数量的增加和网络环境的复杂化&#xff0c;直播过程中可能会遇到网络波动、IP封禁等问题。通过使用代理IP&#xff0c;可以有效解决这些问题&#xff0c;提升直播效果。本文将详细…

Python | Leetcode Python题解之第406题根据身高重建队列

题目&#xff1a; 题解&#xff1a; class Solution:def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:people.sort(keylambda x: (-x[0], x[1]))n len(people)ans list()for person in people:ans[person[1]:person[1]] [person]return ans

SAP自动化-ME12批量更新最后一行的价格

Python源码 #-Begin-----------------------------------------------------------------#-Includes-------------------------------------------------------------- import sys, win32com.client import os import time#-Sub Main-----------------------------------------…

MacOS wine中文乱码问题

安装wine 1、brew update 执行失败&#xff0c;提示安装如下 2、git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow 3、git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow 3、brew update 4、brew in…

c语言是干嘛的

C语言是一种通用的、过程式的编程语言&#xff0c;主要用于系统编程、底层开发和各种高性能应用。它由丹尼斯里奇&#xff08;Dennis Ritchie&#xff09;于1972年在贝尔实验室开发&#xff0c;最初是为了实现UNIX操作系统。 C语言的主要用途&#xff1a; 系统编程&#xff1a…

RK3576芯片在智能家居里中型智慧屏产品的应用方案分析

智能家居在近年来得到了快速发展&#xff0c;AI技术不断发展&#xff0c;人机交互十分成熟&#xff0c;各种家电也都迎来了智能化浪潮&#xff0c;智能家居为人们提供了优秀的产品体验&#xff0c;受到主流消费者的青睐&#xff0c;智能家居里的中型智慧屏产品也随之兴起。 瑞芯…

多速率信号处理-插值和插值滤波器

插值意味着提高采样率&#xff0c;故而被称为上采样&#xff08;Up Sample&#xff09;。设原始序列为 x ( n ) x(n) x(n)&#xff0c;采样率为 f x f_x fx​&#xff0c;插值因子为 L L L&#xff0c;则插值的过程为原始序列每相邻两个样点之间插入 L − 1 L-1 L−1个 0 0 0构…

AI 加持的云端 IDE——三种方法高效开发前后端聊天交互功能

以下是「豆包 MarsCode 体验官」优秀文章&#xff0c;作者努力的小雨。 豆包 MarsCode 豆包MarsCode 编程助手支持的 IDE: 支持 Visual Studio Code 1.67.0 及以上版本&#xff0c;以及 JetBrains 系列 IDE&#xff0c;如 IntelliJ IDEA、Pycharm 等&#xff0c;版本要求为 22…

Nginx+Tomcat(负载均衡、动静分离)

目录 一、Nginx概述 1.Nginx应用 二、正向代理和反向代理 1.正向代理 1.1主要作用 1.2工作原理 2.反向代理 2.1主要作用 2.2工作原理 三、负载均衡模式 1.轮询 2.最少连接数 3.IP 哈希 4.加权轮询 5.最少时间算法 6.一致性哈希 四、规划部署负载均衡和反向…

HarmonyOS学习(十二)——数据管理(一)分布式数据

文章目录 1、分布式数据服务概述2、KV数据模型&#xff08;键值对数据库&#xff09;3、分布式数据服务的约束和限制4、接口说明5、分布式数据服务开发步骤5.1、导入模块5.2、构造分布式数据库管理类实例5.3、获取、创建分布式数据库5.4、订阅分布式数据库的数据变化5.5、插入数…

canal.adapter同步 ES 索引创建 大概配置详情

canal.adapter同步 ES 索引创建 大概配置详情 PUT /test {"settings": {"number_of_shards": 1,"number_of_replicas": 0,"analysis": {"analyzer": {"htmlStripAnalyzer": {"filter": ["lower…