SpringBoot 服务启动过程事件执行顺序解析
·
Spring Boot核心事件执行顺序(基于EventPublishingRunListener)
基于源码验证: 基于Spring Boot源码分析,事件执行顺序严格按照应用生命周期阶段划分,包含您提供的新增源码。
// EventPublishingRunListener.java - 完整事件发布实现
public class EventPublishingRunListener implements SpringApplicationRunListener {
@Override
public void starting() {
this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
this.initialMulticaster.multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
this.initialMulticaster.multicastEvent(new ApplicationContextInitializedEvent(this.application, this.args, context));
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));
}
@Override
public void started(ConfigurableApplicationContext context, Duration timeTaken) {
context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context, timeTaken));
AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
}
@Override
public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context, timeTaken));
AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
// 异常处理事件
}
}
完整事件执行顺序表(包含EventPublishingRunListener方法对应)
| 执行阶段 | 事件类型 | 触发时机 | 执行顺序 | 对应Listener方法 | 事件含义 |
|---|---|---|---|---|---|
| 启动前 | ApplicationStartingEvent | 应用开始启动,环境准备之前 | 1 | starting() | 启动流程开始 |
| 环境准备 | ApplicationEnvironmentPreparedEvent | Environment准备完成,上下文创建前 | 2 | environmentPrepared() | 环境配置就绪 |
| 上下文准备 | ApplicationContextInitializedEvent | ApplicationContext创建并初始化后 | 3 | contextPrepared() | 上下文实例创建 |
| Bean加载 | ApplicationPreparedEvent | Bean定义加载完成,刷新前 | 4 | contextLoaded() | Bean定义加载 |
| 上下文刷新 | ContextRefreshedEvent | ApplicationContext刷新完成 | 5 | Spring框架内部触发 | 上下文完全刷新 |
| 启动完成 | ApplicationStartedEvent | 应用启动完成,命令行Runner执行前 | 6.1 | started()第1行 | 框架启动完成 |
| 存活状态 | LivenessState.CORRECT | 应用内部存活状态确认 | 6.2 | started()第2行 | 应用存活检查通过 |
| Runner执行 | CommandLineRunner/ApplicationRunner | 在ApplicationStartedEvent之后执行 | 7 | Runner接口实现 | 自定义启动逻辑 |
| 就绪阶段 | ApplicationReadyEvent | 所有Runner执行完成,应用完全就绪 | 8.1 | ready()第1行 | 应用完全就绪 |
| 流量接收 | ReadinessState.ACCEPTING_TRAFFIC | 应用确认可以接收外部流量 | 8.2 | ready()第2行 | 可接收外部流量 |
| 异常处理 | ApplicationFailedEvent | 启动过程中发生异常 | - | failed() | 启动失败处理 |
关键源码分析:各方法事件发布明细
// started()方法 - 两个事件的发布
@Override
public void started(ConfigurableApplicationContext context, Duration timeTaken) {
context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context, timeTaken));
AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
}
// ready()方法 - 两个事件的发布
@Override
public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context, timeTaken));
AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
}
EventPublishingRunListener接口方法完整映射
| Listener方法名 | 触发的事件 | 方法参数 | 阶段描述 |
|---|---|---|---|
| starting() | ApplicationStartingEvent | 无 | 应用开始启动 |
| environmentPrepared() | ApplicationEnvironmentPreparedEvent | ConfigurableEnvironment | 环境准备完成 |
| contextPrepared() | ApplicationContextInitializedEvent | ConfigurableApplicationContext | 上下文准备完成 |
| contextLoaded() | ApplicationPreparedEvent | ConfigurableApplicationContext | Bean定义加载完成 |
| started() | ApplicationStartedEvent + LivenessState.CORRECT | ConfigurableApplicationContext, Duration | 应用启动完成 |
| ready() | ApplicationReadyEvent + ReadinessState.ACCEPTING_TRAFFIC | ConfigurableApplicationContext, Duration | 应用完全就绪 |
| failed() | ApplicationFailedEvent | ConfigurableApplicationContext, Throwable | 启动失败处理 |
设计理念深度分析
方法-事件映射的清晰性:
• 每个Listener方法对应特定的生命周期阶段
• 事件发布顺序严格遵循方法调用顺序
• 多事件方法(started/ready)保持内部事件的执行顺序一致性
阶段递进关系:
starting() → environmentPrepared() → contextPrepared() → contextLoaded() → started() → ready()
最终结论: EventPublishingRunListener 的每个方法都精确对应 Spring Boot 应用生命周期的特定阶段,事件发布顺序严格遵循方法调用顺序。started() 和 ready() 方法内部的事件执行顺序体现了从"框架启动完成"到"业务完全就绪"的递进关系,设计严谨且语义明确。
(END)
更多推荐
所有评论(0)