首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring 入門(四):Bean 生命周期全流程解析——ApplicationContext vs BeanFactory 差異對比

     編輯:Java 相關知識

Bean 生命周期核心價值

理解生命周期能精準控制初始化/銷毀邏輯、排查依賴注入順序問題、實現優雅啟動關閉。

ApplicationContext 中 Bean 完整生命周期(10 步)

  1. 實例化:根據 Bean 定義創建實例
  2. 依賴注入:設置所有屬性
  3. BeanNameAware:setBeanName(String beanId)
  4. BeanFactoryAware:setBeanFactory(BeanFactory factory)
  5. ApplicationContextAware:setApplicationContext(ApplicationContext ctx) (BeanFactory 無此步)
  6. BeanPostProcessor 前置:postProcessBeforeInitialization(bean, beanName)
  7. 初始化方法:init-method="init" 或 InitializingBean.afterPropertiesSet()
  8. BeanPostProcessor 後置:postProcessAfterInitialization(bean, beanName)
  9. 可用階段:Bean 正常服務業務請求
  10. 銷毀:DisposableBean.destroy() 或 destroy-method="close"

ApplicationContext 生命周期圖

完整代碼驗證

實現所有 Aware 接口的 Bean

public class HelloDaoImpl implements BeanNameAware, BeanFactoryAware, InitializingBean, ApplicationContextAware, DisposableBean {
    private String content;
    public HelloDaoImpl() { System.out.println("---實例化"); }
    public void setContent(String content) { System.out.println("---依賴注入: " + content); this.content = content; }
    @Override public void setBeanName(String beanId) { System.out.println("---BeanNameAware: " + beanId); }
    @Override public void setBeanFactory(BeanFactory factory) { System.out.println("---BeanFactoryAware: " + factory.getClass()); }
    @Override public void setApplicationContext(ApplicationContext ctx) { System.out.println("---ApplicationContextAware: " + ctx); }
    @Override public void afterPropertiesSet() { System.out.println("---InitializingBean.afterPropertiesSet"); }
    public void init() { System.out.println("---自定義 init-method"); }
    @Override public void destroy() { System.out.println("---DisposableBean.destroy"); }
    public void close() { System.out.println("---自定義 destroy-method"); }
}

BeanPostProcessor 實現

public class BeanPostProcessorImpl implements BeanPostProcessor {
    @Override public Object postProcessBeforeInitialization(Object bean, String beanName) {
        System.out.println("---前置處理: " + beanName); return bean;
    }
    @Override public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("---後置處理: " + beanName); return bean;
    }
}

XML 配置

<bean id="helloDaoImpl" class="www.csdn.spring.dao.HelloDaoImpl"
      scope="singleton" lazy-init="false"
      init-method="init" destroy-method="close">
    <property name="content" value="陳老師早上好!"/>
</bean>
<bean class="www.csdn.spring.dao.BeanPostProcessorImpl"/> <!-- 全局後置處理器 -->

測試類(關閉容器觸發銷毀)

public class BeanTest {
    @Test public void test() {
        ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:spring-dao.xml");
        ctx.close(); // 關鍵:觸發銷毀回調
    }
}

運行輸出

運行輸出

BeanFactory 生命周期差異

  • 無 ApplicationContextAware 回調
  • 需手動註冊 BeanPostProcessor:factory.addBeanPostProcessor(new BeanPostProcessorImpl())
  • 銷毀調用:factory.destroySingletons()
  • 懶加載:getBean() 時才創建單例;ApplicationContext 啟動時預創建所有單例

BeanFactory 運行輸出 BeanFactory 生命周期圖

核心差異總結表

特性ApplicationContextBeanFactory
ApplicationContextAware✅ 支持❌ 不支持
BeanPostProcessor 註冊自動掃描手動 addBeanPostProcessor
單例 Bean 創建時機容器啟動時預創建首次 getBean() 時懶創建
國際化/事件/資源加載內置支持需額外擴展
適用場景企業級應用標準容器測試、輕量級嵌入式

現代 Spring 最佳實踐

  • 優先使用 @PostConstruct / @PreDestroy (JSR-250) 替代接口/XML 配置
  • 實現 SmartInitializingSingleton 在所有單例創建完後執行邏輯
  • 使用 ApplicationListener<ContextRefreshedEvent> 監聽容器就緒事件
  • 優雅關閉:ConfigurableApplicationContext.close() 或 Spring Boot SpringApplication.exit()

掌握生命周期,讓 Bean 在正確時間做正確的事!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved