一、Spring Boot 核心事件类型概览
| 事件名称 | 触发时机(精准描述) | 实际应用场景 |
|---|---|---|
| ApplicationStartingEvent | 应用启动初期(SpringApplication.run() 方法执行后立即触发),此时上下文(ApplicationContext)未创建,仅初始化基本运行环境 |
适合在应用启动最早期执行轻量级操作,例如:日志系统预配置;启动参数校验;第三方组件初始化(无需上下文依赖) |
| ApplicationEnvironmentPreparedEvent | 环境(Environment)对象创建完成后触发,上下文仍未初始化,但已加载系统属性、环境变量、配置文件(application.yml/properties、bootstrap 等) | 核心场景:配置文件动态修改 / 补充;环境变量注入与校验;Spring Cloud 组件初始化;自定义配置源加载(如从数据库读取配置) |
| ApplicationContextInitializedEvent | ApplicationContext 创建完成后触发,且已执行所有 ApplicationContextInitializer 初始化器,但 Bean 定义尚未加载(BeanDefinition 未注册) |
适合:上下文级别的配置修改;动态注册 Bean 定义;初始化上下文相关的工具类 |
| ApplicationPreparedEvent | ApplicationContext 初始化完成,Bean 定义已加载(XML / 注解扫描的 Bean 已注册),但 Bean 实例未创建(未执行 refresh() 流程) |
应用场景:Bean 定义加载后的校验(如是否缺失关键 Bean);初始化需要依赖 Bean 定义的组件;日志系统与 Spring 容器绑定 |
| ContextRefreshedEvent | ApplicationContext 执行 refresh() 流程完成后触发,Bean 实例已创建(单例 Bean 完成初始化),依赖注入完成,容器处于可用状态 |
最常用的事件之一,适合:初始化需要依赖容器中 Bean 的组件(如调用 @Service 层方法加载缓存);校验容器中 Bean 的状态(如数据源连接是否正常);启动定时任务、消息消费者(如 RabbitMQ/Kafka 消费者) |
| ApplicationStartedEvent | Spring Boot 调用自定义的 afterRefresh() 方法后触发,此时容器已完全初始化,所有 Bean 均可用,应用即将进入运行状态 |
适合执行需要容器完全就绪的操作,例如:中间件连接校验;业务初始化任务;启动通知推送 |
| ApplicationReadyEvent | Spring Boot 启动流程全部完成,应用已完全就绪,可接收外部请求(如 HTTP 请求、RPC 调用) | 核心场景:对外暴露应用启动完成的信号(如注册到服务发现中心);执行启动后的收尾工作(如清理启动临时文件);触发依赖当前应用的外部系统(如通知网关应用已就绪) |
| ApplicationFailedEvent | Spring Boot 启动过程中发生异常(如配置错误、Bean 初始化失败、中间件连接超时),导致启动失败时触发 | 应用场景:启动失败告警(如通过监控系统发送告警信息);失败原因快速定位(日志记录关键异常信息);资源清理(避免内存泄漏、端口占用) |
| ContextClosedEvent | ApplicationContext 关闭时触发(如应用正常停机、意外崩溃),容器将销毁所有 Bean 实例 | 适合:资源释放(如关闭数据库连接池、Redis 连接、消息队列连接);数据持久化(如保存缓存数据到数据库);停机通知(如告知注册中心服务下线) |
二、各事件对应的核心监听器及作用详解
1. ApplicationStartingEvent 对应的监听器
核心监听器:LoggingApplicationListener 作为应用启动最早期的监听器,其核心作用是完成日志系统的初始化:
- 自动检测 classpath 中存在的日志框架(优先级:Logback > Log4j2 > JUL),结合
spring-boot-starter-logging依赖自动选择默认实现; - 加载类路径下的日志配置文件(支持 logback-spring.xml、log4j2.xml、logging.properties 等格式);
- 初始化日志上下文(如 Logback 的 LoggerContext),为后续启动流程提供日志输出支持。
2. ApplicationEnvironmentPreparedEvent 对应的监听器
该事件是监听器最密集的阶段,涵盖配置加载、日志更新、异步初始化等核心操作:
- BootstrapApplicationListener(Spring Cloud 专属):专为微服务场景设计,优先加载 bootstrap.yml/properties 配置文件,初始化 Spring Cloud Config、Nacos 等配置中心客户端,同时完成注册中心(Eureka、Nacos)的连接前置准备,确保配置中心的配置优先于应用配置生效;
- LoggingSystemShutdownListener:清理日志系统在启动初期创建的临时资源,包括临时日志文件、未关闭的日志句柄等,避免资源泄漏;
- EnvironmentPostProcessorApplicationListener :触发所有
EnvironmentPostProcessor实现类的执行,核心职责是加载多环境配置(如 application-dev.yml、application-prod.yml)、解析配置占位符(${})、合并系统属性与环境变量,确保 Environment 对象中的配置完整可用; - LoggingApplicationListener(二次执行) :基于已初始化的 Environment 对象,更新日志级别配置(如读取
logging.level.root=INFO、logging.level.com.example=DEBUG等配置),使日志系统适配当前环境的配置要求; - BackgroundPreinitializer:采用异步方式初始化非核心组件,例如 Jackson 消息转换器、JSR-380 Validation 校验器等,减少同步初始化对启动速度的影响,提升应用启动效率;
- DelegatingApplicationListener :通过读取配置项
context.listener.classes中的全类名,实例化并注册用户自定义的监听器,这些自定义监听器的执行顺序独立于内置监听器,支持灵活扩展。
3. ApplicationContextInitializedEvent 对应的监听器
该事件无内置核心监听器,主要用于用户扩展场景:
- 允许开发者通过自定义监听器,对 ApplicationContext 进行个性化配置,例如设置自定义资源加载器、环境变量处理器、类型转换服务等;
- 支持动态注册
BeanDefinitionRegistryPostProcessor,在 Bean 定义加载前动态添加或修改 BeanDefinition,实现 Bean 的动态注册(如根据环境动态注册不同的数据源 Bean)。
4. ApplicationPreparedEvent 对应的监听器
核心监听器:LoggingApplicationListener(三次执行) 此时 Bean 定义已完成注册,但尚未实例化,该监听器的核心作用是:
- 将日志系统的核心 Bean(如 Logback 的 LoggerContext、Log4j2 的 LoggerContext)注入 Spring 容器,使其成为 Spring 管理的 Bean;
- 绑定日志相关的 Spring 组件(如
LoggingSystem实例、LoggerGroup配置),支持后续通过@Autowired注入日志相关 Bean,方便业务代码中灵活操作日志系统。
5. ContextRefreshedEvent 对应的监听器
核心监听器:RestartListener(Spring Boot DevTools 专属) 该监听器仅在启用 Spring Boot DevTools 热部署功能时生效,核心职责是:
- 检测应用是否处于热部署重启模式,区分正常启动与热部署重启场景;
- 热部署重启后,重新触发
ApplicationEnvironmentPreparedEvent,确保配置中心的最新配置、多环境配置重新加载,避免热部署后配置失效; - 清理旧容器的残留资源(如旧的 Bean 实例、数据库连接池),防止内存泄漏,保证热部署后的容器干净可用。
6. ApplicationStartedEvent 对应的监听器
无内置核心监听器,完全为用户扩展设计:
- 支持在应用容器完全就绪后,执行健康检查操作,例如校验数据库、Redis、RabbitMQ 等中间件的连接状态;
- 可发送启动成功通知,例如通过钉钉、企业微信、邮件等方式告知运维人员应用已启动;
- 适合执行业务初始化任务,如初始化字典表数据、权限配置数据、缓存预热等操作。
7. ApplicationReadyEvent 对应的监听器
无内置核心监听器,是应用启动完成的最终信号:
- 常用于向服务发现中心(如 Eureka、Nacos)注册服务实例,告知注册中心应用已完全就绪,可接收外部请求;
- 可执行启动后的收尾工作,例如清理启动过程中生成的临时文件、删除启动锁等;
- 支持触发依赖当前应用的外部系统操作,例如通知 API 网关更新路由规则、告知下游服务当前应用已可用。
8. ApplicationFailedEvent 对应的监听器
内置失败处理监听器,核心作用是应对启动异常:
- 捕获启动过程中的所有异常(如配置解析失败、Bean 初始化异常、中间件连接超时等),记录包含异常堆栈的详细日志,方便问题定位;
- 清理启动过程中已创建的资源,包括数据库连接、Redis 连接、临时文件、网络端口等,避免资源占用或泄漏;
- 支持扩展自定义失败通知逻辑,例如通过监控系统(如 Prometheus + Grafana)发送告警、调用运维接口触发紧急处理流程。
9. ContextClosedEvent 对应的监听器
核心监听器:ParentContextCloserApplicationListener 该监听器专注于上下文关闭时的资源清理,核心职责是:
- 检测当前 ApplicationContext 是否存在父上下文(ParentApplicationContext,常见于 Spring Cloud 子容器场景);
- 当子上下文关闭时(如应用停机),同步关闭父上下文,避免父上下文残留导致的资源泄漏;
- 销毁父上下文关联的核心 Bean,包括数据源连接池、Redis 连接工厂、消息队列生产者 / 消费者等,确保资源完全释放。
三、Spring Boot 启动时的事件顺序
graph TD
A["ApplicationStartingEvent→ 启动初期,上下文未创建"] -->|环境初始化完成| B["ApplicationEnvironmentPreparedEvent→ Environment 就绪,配置加载完成"]
B -->|"上下文创建+初始化器执行"| C["ApplicationContextInitializedEvent→ 上下文就绪,Bean定义未加载"]
C -->|Bean定义加载完成| D["ApplicationPreparedEvent→ Bean注册完成,未实例化"]
D -->|"refresh()执行完成,Bean实例化"| E["ContextRefreshedEvent→ 容器就绪,Bean可用"]
E -->|"afterRefresh()执行完成"| F["ApplicationStartedEvent→ 应用即将就绪"]
F -->|启动流程全部完成| G["ApplicationReadyEvent→ 完全就绪,可接收请求"]
style A fill:#f9f,stroke:#333,stroke-width:2px
style G fill:#9f9,stroke:#333,stroke-width:2px
补充说明:
- 异常分支 :若任意步骤发生异常,将直接触发
ApplicationFailedEvent,启动流程终止,同时执行异常清理逻辑; - 顺序不可变 :上述事件顺序由 Spring Boot 内核(
SpringApplication类)硬编码控制,自定义监听器仅能监听事件,无法修改内置事件的触发顺序; - Spring Cloud 影响 :引入 Spring Cloud 依赖后,
ApplicationEnvironmentPreparedEvent会优先触发BootstrapApplicationListener,提前加载 bootstrap 配置,其余事件顺序保持不变; - DevTools 影响 :启用 Spring Boot DevTools 后,
ContextRefreshedEvent会触发RestartListener,支持热部署时的配置重新加载和旧资源清理。