spring boot 初始化机制按执行时机分为四类:①@postconstruct用于单bean依赖注入后轻量初始化;②commandlinerunner/applicationrunner在所有bean就绪后执行,支持排序;③applicationcontextinitializer在容器refresh前修改环境配置;④applicationreadyevent监听器确保应用完全就绪后触发。

Spring Boot 提供了多种初始化器机制,用于在应用启动的不同阶段加载数据或执行预设逻辑。选择哪种方式,取决于你要操作的数据范围、依赖关系、执行时机,以及是否需要跨 Bean 协作或分布式控制。
@PostConstruct:单 Bean 初始化最轻量的方式
适用于某个 Service 或 Component 内部的简单数据加载,比如从数据库查字典表填充内存 List、初始化缓存 Map 等。
- 必须标注在非静态、无参、void 返回的方法上
- 执行时机是该 Bean 依赖注入完成后、被其他 Bean 使用前
- 不支持跨 Bean 顺序控制,也不能访问 Spring 上下文中的其他未就绪 Bean
- 不能抛受检异常(需 try-catch 包裹)
CommandLineRunner / ApplicationRunner:启动后统一入口,支持排序与参数
这是最常用、最推荐的启动后初始化方式,适合多数业务场景,如加载全局配置、预热 Redis、校验第三方服务连通性等。
- 两者都要求实现接口并标记 @Component;区别在于参数类型:CommandLineRunner 接收 String[],ApplicationRunner 接收 ApplicationArguments(可解析 option/non-option 参数)
- 用 @Order(n) 控制执行顺序,n 越小越早执行(如 @Order(1) 优先于 @Order(10))
- 所有 Runner 在所有 Bean 初始化完成后才执行,能安全调用任意已注册 Bean
- 若初始化耗时或可能失败,建议包裹在新线程中,避免阻塞主线程导致启动失败
ApplicationContextInitializer:容器上下文级初始化(早于 Bean 创建)
适用于修改环境变量、注入额外 PropertySource、动态添加配置项等底层操作,比如从远程配置中心拉取配置并提前注入 Environment。
- 执行时机最早——在 ConfigurableApplicationContext 构造完成、但尚未 refresh 之前
- 需通过 spring.factories、application.yml 的 context.initializer.classes,或 SpringApplication.addInitializers() 显式注册
- 常配合 @Order 或实现 Ordered 接口控制多个 Initializer 的执行顺序
- 不能直接使用 @Autowired 注入其他 Bean(此时 BeanFactory 还未初始化)
ApplicationRunner + ApplicationReadyEvent:确保“完全就绪”后再执行
当你的初始化逻辑依赖某些异步组件(如 Netty 启动完成、Actuator 端点可用、消息监听器已注册),单纯靠 Runner 可能不够稳,这时可监听事件。
- 使用 @EventListener(ApplicationReadyEvent.class) 标注方法
- 该事件在 Spring 容器 refresh 完成、所有 Runner 执行完毕、应用真正对外提供服务前触发
- 适合强一致性要求的场景,例如向注册中心上报实例、开启定时任务调度器、发送启动成功通知











