Spring IoC 容器管理 Bean 生命週期的核心機制,包含作用域控制、實例化時機、初始化/銷毀回調。本文透過實戰代碼演示預設單例、原型模式、懶加載配置與生命週期介面應用。
<!-- 預設 singleton:容器啟動建立單例,後續 getBean 返回同一實例 -->
<bean id="people" class="com.example.People" />
<!-- prototype:每次 getBean 均建立新實例 -->
<bean id="people" class="com.example.People" scope="prototype" />
| 特性 | singleton | prototype |
|---|---|---|
| 實例數量 | 容器中唯一共享實例 | 每次請求新建實例 |
| 建立時機 | 容器啟動時(預設) | 首次 getBean 時 |
| 銷毀回調 | 容器關閉時執行 | 不執行(容器不管銷毀) |
| 適用場景 | 無狀態服務、DAO、Controller | 有狀態物件、每次需獨立狀態 |
<bean id="people" class="com.example.People" lazy-init="true" />
<!-- 值選項:default(等同 false)、true、false -->
true:首次 `getBean()` 時才實例化(僅對 singleton 生效)。false/default:容器啟動階段預先實例化。public class People implements InitializingBean, DisposableBean {
@Override public void afterPropertiesSet() { /* 初始化邏輯 */ }
@Override public void destroy() { /* 銷毀邏輯 */ }
}
<bean id="people" class="com.example.People"
init-method="init" destroy-method="cleanup" />
@Component public class People {
@PostConstruct public void init() { ... }
@PreDestroy public void cleanup() { ... }
}
實例化
→ 屬性注入 (setter/自動裝配)
→ Aware 介面回調 (BeanNameAware, BeanFactoryAware, ApplicationContextAware)
→ BeanPostProcessor.postProcessBeforeInitialization
→ 初始化回調 (afterPropertiesSet / @PostConstruct / init-method)
→ BeanPostProcessor.postProcessAfterInitialization
→ Bean 就緒可用
→ (容器關閉/請求結束)
→ 銷毀回調 (destroy / @PreDestroy / destroy-method)
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
People p1 = ctx.getBean("people", People.class);
People p2 = ctx.getBean("people", People.class);
System.out.println(p1 == p2); // singleton: true | prototype: false
((ConfigurableApplicationContext) ctx).close(); // 觸發銷毀回調
singleton,有狀態才用 prototype。lazy-init="true"`。@PostConstruct/@PreDestroy,避免 XML 與代碼分離維護困難。
4. prototype Bean 搭配 `ObjectFactory` 或 `Provider` 注入,解決單例注入原型 Bean 只能拿到同一實例的問題。
掌握 Bean 生命週期全景圖,能精準控制資源分配與釋放,排查初始化順序異常、記憶體洩漏等疑難雜症。