文章目錄
- 🌱 《Spring IOC核心:Bean生命周期全解析》
- 1?? 引言:Bean 生命周期為什么重要?
- 2?? Bean 生命周期概覽(圖示 + 簡要說明)
- 3?? 每一步詳細解析(源碼理解 + 示例)
- 3.1 🧱 實例化(構造函數)
- 3.2 🧩 屬性注入(Setter、@Value、@Autowired)
- 3.3 🔎 Aware 接口(Bean 開始“認識環境”)
- 3.4 ?? 初始化階段(核心階段!)
- ? 方式1:實現 InitializingBean
- ? 方式2:使用 @PostConstruct
- ? 方式3:init-method 配置(XML 或 @Bean)
- ? BeanPostProcessor:初始化前后增強
- 3.5 🧑?🔧 使用階段(容器托管中)
- 3.6 💣 銷毀階段
- ? 方式1:實現 DisposableBean
- ? 方式2:使用 @PreDestroy
- ? 方式3:destroy-method 配置
- 4?? 實戰演示:一個 Bean 完整生命周期打印示例
- 5?? 常見誤區與調試技巧
- 6?? 總結 & 推薦實踐
- 📘 延伸閱讀
🌱 《Spring IOC核心:Bean生命周期全解析》
目標讀者:
使用 Spring 的 Java 后端開發者,
想深入理解 Bean 的創建、初始化、銷毀全過程,
以寫出更加健壯、可控、可調試的應用代碼。
1?? 引言:Bean 生命周期為什么重要?
Bean,不是你
new
出來的,而是 Spring 創建并“托管”的!
在 Spring 框架中,Bean 是最核心的組件之一,但我們很多時候對它的 “出生 → 成長 → 退休” 過程了解得并不完整。
類比一下:
Spring 就像一個“高級托兒所”,Bean 是被托管的小朋友,從出生到離園都有嚴格的流程規范。
理解這個生命周期,不僅能幫助我們進行框架擴展、調試 Bug,更是理解 Spring “魔法”的第一步!
2?? Bean 生命周期概覽(圖示 + 簡要說明)
┌────────────┐│ 實例化 Instantiation└────┬───────┘↓┌────────┴────────┐│ 屬性填充 Populate│└────────┬────────┘↓┌────────────┴────────────┐│ Aware 回調(BeanNameAware等)└────────────┬────────────┘↓┌────────────┴────────────┐│ 初始化:@PostConstruct / init-method│ + BeanPostProcessor 執行└────────────┬────────────┘↓┌────────┴────────┐│ Bean 被使用中 │└────────┬────────┘↓┌────────────┴────────────┐│ 銷毀:@PreDestroy / destroy-method└─────────────────────────┘
3?? 每一步詳細解析(源碼理解 + 示例)
3.1 🧱 實例化(構造函數)
Spring 首先通過 構造函數反射 實例化 Bean。
public class MyBean {public MyBean() {System.out.println("1?? 實例化階段");}
}
3.2 🧩 屬性注入(Setter、@Value、@Autowired)
Spring 在實例化后,為 Bean 注入屬性。
@Component
public class MyBean {@Value("${my.value:default}")private String value;@Autowiredprivate Dependency dependency;public void setValue(String value) {System.out.println("2?? 屬性注入:" + value);this.value = value;}@Autowiredpublic void setDependency(Dependency dependency) {System.out.println("2?? 屬性注入:依賴注入完成");this.dependency = dependency;}
}
3.3 🔎 Aware 接口(Bean 開始“認識環境”)
Bean 想知道自己叫什么、誰在托管我、我在哪個容器中?就實現這些接口。
@Component
public class MyBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware {public void setBeanName(String name) {System.out.println("3?? BeanNameAware:我的名字是 " + name);}public void setBeanFactory(BeanFactory factory) {System.out.println("3?? BeanFactoryAware:我被 BeanFactory 托管");}public void setApplicationContext(ApplicationContext ctx) {System.out.println("3?? ApplicationContextAware:我已感知到容器");}
}
3.4 ?? 初始化階段(核心階段!)
Spring 讓你“準備就緒”,可以做初始化邏輯了。
? 方式1:實現 InitializingBean
@Override
public void afterPropertiesSet() throws Exception {System.out.println("4?? InitializingBean:屬性注入后初始化");
}
? 方式2:使用 @PostConstruct
@PostConstruct
public void init() {System.out.println("4?? @PostConstruct:初始化方法執行");
}
? 方式3:init-method 配置(XML 或 @Bean)
@Bean(initMethod = "init")
public MyBean myBean() {return new MyBean();
}
? BeanPostProcessor:初始化前后增強
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {public Object postProcessBeforeInitialization(Object bean, String name) {System.out.println("?? Before Init: " + name);return bean;}public Object postProcessAfterInitialization(Object bean, String name) {System.out.println("?? After Init: " + name);return bean;}
}
3.5 🧑?🔧 使用階段(容器托管中)
此階段 Bean 被容器管理、可被其他組件注入、調用。
@Component
public class UserService {@Autowiredprivate MyBean myBean;public void use() {System.out.println("5?? Bean 正在被使用中");}
}
3.6 💣 銷毀階段
Spring 容器關閉時,執行銷毀邏輯。
? 方式1:實現 DisposableBean
@Override
public void destroy() throws Exception {System.out.println("6?? DisposableBean:銷毀中");
}
? 方式2:使用 @PreDestroy
@PreDestroy
public void destroyMethod() {System.out.println("6?? @PreDestroy:銷毀邏輯");
}
? 方式3:destroy-method 配置
@Bean(destroyMethod = "cleanup")
public MyBean myBean() {return new MyBean();
}
?? 注意:@Scope(“prototype”) 的 Bean 容器不負責銷毀!需手動釋放資源。
4?? 實戰演示:一個 Bean 完整生命周期打印示例
@Component
public class LifeCycleBean implements BeanNameAware, InitializingBean, DisposableBean {public LifeCycleBean() {System.out.println("1?? 構造方法執行:實例化");}@Autowiredpublic void setDependency(Dependency dep) {System.out.println("2?? 屬性注入");}@Overridepublic void setBeanName(String name) {System.out.println("3?? 感知容器:我的名字是 " + name);}@PostConstructpublic void postConstruct() {System.out.println("4?? 初始化:@PostConstruct");}@Overridepublic void afterPropertiesSet() {System.out.println("4?? 初始化:afterPropertiesSet");}@PreDestroypublic void preDestroy() {System.out.println("6?? 銷毀:@PreDestroy");}@Overridepublic void destroy() {System.out.println("6?? 銷毀:destroy()");}
}
控制臺輸出:
1?? 構造方法執行:實例化
2?? 屬性注入
3?? 感知容器:我的名字是 lifeCycleBean
4?? 初始化:@PostConstruct
4?? 初始化:afterPropertiesSet
?? Bean 使用中...
6?? 銷毀:@PreDestroy
6?? 銷毀:destroy()
5?? 常見誤區與調試技巧
問題描述 | 可能原因 |
---|---|
@PostConstruct 不執行 | Bean 沒被容器管理,或被 @Configuration 注冊成了 Lite 模式 |
BeanPostProcessor 順序異常 | 實現了多個 BPP 接口但未排序,可實現 Ordered 解決 |
原型 Bean 不執行 destroy | @Scope("prototype") 的 Bean 不受容器銷毀管理 |
生命周期日志沒打印 | @Component 沒掃到;或被懶加載;或依賴未注入 |
6?? 總結 & 推薦實踐
- Bean 生命周期是 Spring 提供擴展能力的核心入口;
- 推薦使用 @PostConstruct 和 @PreDestroy 進行初始化/銷毀管理;
- 多個初始化方式優先級為:@PostConstruct > InitializingBean > init-method;
- 掌握 Bean 生命周期 = 掌握 Spring 魔法的第一步!
📘 延伸閱讀
- Spring 源碼 AbstractBeanFactory
- 《Spring 實戰》第 4 章 Bean 生命周期
- 官方文檔:Bean Lifecycle