Spring Boot 提供 SpringApplicationRunListener、ApplicationRunner 和 CommandLineRunner 三种监听器:前者监听启动全过程各阶段(如 starting、environmentPrepared),需通过 spring.factories 注册且无法依赖注入;后两者在容器启动后执行,支持 @Order 控制顺序。

在 Spring Boot 中,可以通过 SpringApplication.run 方法注册自定义启动监听器,实现对应用生命周期(如环境准备、上下文刷新、启动完成等阶段)的细粒度控制。
使用 SpringApplication.addListeners 添加监听器
最直接的方式是在调用 run() 前,通过 addListeners() 方法注册监听器。监听器需实现 ApplicationRunner、CommandLineRunner 或 SpringApplicationRunListener 接口:
-
ApplicationRunner / CommandLineRunner:适合在容器启动后、业务逻辑执行前运行代码,按
@Order或实现Ordered接口控制顺序。 -
SpringApplicationRunListener:更底层,可监听从启动开始到上下文刷新完成的全过程(如
starting、environmentPrepared、contextPrepared、contextLoaded、started、running等阶段),需配合spring.factories文件或手动传入。
在 main 方法中注册 Runner 类型监听器
以 ApplicationRunner 为例,在主类中添加 Bean 或直接 new 实例并加入:
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MyApplication.class);
app.addListeners(new ApplicationRunner() {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("应用已启动,Bean 已加载完成");
}
});
app.run(args);
}
也可将监听逻辑封装为独立 Bean,Spring Boot 会自动发现并执行:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
@Component
@Order(1)
public class StartupCheckRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
// 执行健康检查、缓存预热等
}
}
实现 SpringApplicationRunListener 自定义启动流程
若需介入更早阶段(比如读取配置前、创建 Environment 前),需实现 SpringApplicationRunListener:
- 新建类实现该接口,重写关键方法(如
starting、environmentPrepared)。 - 在
META-INF/spring.factories中声明:
org.springframework.boot.SpringApplicationRunListener=\
com.example.MySpringApplicationRunListener - 注意:该监听器构造时接收
SpringApplication和String[] args,不能依赖注入其他 Bean(此时 IoC 容器尚未初始化)。
区分监听时机与执行顺序
不同监听器触发时机不同,合理选择能避免空指针或上下文未就绪问题:
-
SpringApplicationRunListener.starting():main 方法刚执行,连 Environment 都没创建。 -
environmentPrepared():Environment 已构建完成,可读取配置属性。 -
contextLoaded():ApplicationContext 已创建、BeanDefinition 已加载,但尚未刷新。 -
started():上下文已刷新,Web 服务器已启动(如 Tomcat),但还没响应请求。 -
running():应用完全就绪,ApplicationRunner和CommandLineRunner此时已执行完毕。

















