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