1. @PostConstruct
- JSR-250 标准注解(不是 Spring 独有),用来标记 Bean 初始化完成后要执行的方法。
- 会在 Bean 的构造方法执行完、依赖注入完成后执行。
使用实例:
@Component
public class Demo {@PostConstructpublic void init() {System.out.println("PostConstruct执行");}
}
执行时机: Bean 构造 → 依赖注入 → @PostConstruct
方法 → 初始化完成
2. InitializingBean (afterPropertiesSet)
- Spring 提供的接口,只要实现了它,就必须实现
afterPropertiesSet()
方法。 afterPropertiesSet()
在 Bean 的依赖注入完成后执行(和 @PostConstruct 类似,但优先级稍后一些)。
使用实例:
@Component
public class Demo implements InitializingBean {@Overridepublic void afterPropertiesSet() {System.out.println("afterPropertiesSet执行");}
}
执行时机: Bean 构造 → 依赖注入 → @PostConstruct
→ afterPropertiesSet
3. ApplicationListener
- Spring 的事件监听器机制的一部分,用于监听 Spring 容器内发生的事件(如 ContextRefreshedEvent、ApplicationReadyEvent 等)。
- 可以实现 ApplicationListener 或使用 @EventListener 注解。
示例:监听 ContextRefreshedEvent
@Component
public class Demo implements ApplicationListener<ContextRefreshedEvent> {@Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {System.out.println("ApplicationListener执行");}
}
执行时机:
- ContextRefreshedEvent:Spring 容器初始化或刷新完成后发布,通常用于监听上下文准备完毕(比 CommandLineRunner 更早一点)。
- ApplicationReadyEvent:Spring Boot 特有,表示整个 Spring Boot 应用完全启动(更接近 CommandLineRunner)。
4. CommandLineRunner
- Spring Boot 提供的接口。实现后会在整个 Spring 容器启动完成(所有 Bean 初始化结束)之后执行。
- 用来执行一些项目启动后的逻辑,比如初始化数据、打印信息。
使用示例:
@Component
public class Demo implements CommandLineRunner {@Overridepublic void run(String... args) {System.out.println("CommandLineRunner执行");}
}
执行时机: Spring 容器完全启动 → run 方法执行 → 也就是在所有 @PostConstruct、InitializingBean 执行完之后
5. Bean生命周期(Spring容器级别)
- 实例化(Instantiation):Spring 通过反射调用构造方法,创建 Bean 实例。
- 属性填充(Dependency Injection):Spring 把依赖(
@Autowired
、@Value
、@Resource
等)注入到 Bean 里。 - BeanPostProcessor 前置处理(postProcessBeforeInitialization):Spring 会调用注册的所有 BeanPostProcess 的
postProcessBeforeInitialization()
。@PostConstruct
的执行就是这里触发的:CommonAnnotationBeanPostProcessor
负责找出@PostConstruct
并执行。 - 初始化(InitializingBean、init-method):如果实现了
InitializingBean
,调用afterPropertiesSet()
。如果在@Bean(initMethod="xxx")
指定了初始化方法,也会执行。 - BeanPostProcessor 后置处理(postProcessAfterInitialization):再次调用注册的 BeanPostProcessor 的
postProcessAfterInitialization()
。比如 AOP、代理包装,就是这一步做的。 - Bean 就绪,可使用:到这里,这个 Bean 就放到 Spring 容器里了,可以被别的 Bean 使用。
实例化 ➜ 依赖注入 ➜ postProcessBeforeInitialization⮑ @PostConstruct
➜ InitializingBean.afterPropertiesSet()
➜ init-method
➜ postProcessAfterInitialization
➜ 可用
6. SpringBoot 的启动时间线(整个应用级别)
SpringApplication.run()
启动入口:创建ApplicationContext
(即Spring容器)。- 准备环境(ApplicationEnvironmentPreparedEvent):配置文件、属性源准备好。
- 容器初始化(ApplicationPreparedEvent):
ApplicationContext
已经创建,但 Bean 还没加载。 - Bean 加载 → Bean 生命周期
- 容器刷新完成(ContextRefreshedEvent):所有 Bean 都加载完成。可以用
ApplicationListener<ContextRefreshedEvent>
在这里干事。 - ApplicationStartedEvent:Spring 容器准备好,还没执行
CommandLineRunner / ApplicationRunner
。 - 执行 CommandLineRunner / ApplicationRunner:所有事件都发完,启动逻辑完成。
- ApplicationReadyEvent:SpringBoot 应用准备就绪,可以对外提供服务了。
SpringApplication.run() ➜ 加载环境 (EnvironmentPrepared)➜ 创建容器 (Prepared)➜ Bean 生命周期 (实例化 ➜ @PostConstruct ➜ afterPropertiesSet)➜ 容器刷新完成 (ContextRefreshedEvent)➜ ApplicationStartedEvent➜ CommandLineRunner / ApplicationRunner➜ ApplicationReadyEvent