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

Spring Bean 生命周期全流程圖解:從實例化到銷毀、Aware 接口、後置處理器、工廠後置處理器完整鏈路

     編輯:Java 相關知識

生命周期總覽(文字版流程圖)

1. 容器啟動 → 讀取配置元數據 (XML/@Configuration)
2. BeanFactoryPostProcessor.postProcessBeanFactory()  // 修改 BeanDefinition
3. 實例化 Bean (構造器/工廠方法)
4. 屬性填充 (Dependency Injection)
5. Aware 接口回調:
   - BeanNameAware.setBeanName()
   - BeanFactoryAware.setBeanFactory()
   - ApplicationContextAware.setApplicationContext()
   - ... 其他 *Aware
6. BeanPostProcessor.postProcessBeforeInitialization()
7. 初始化回調:
   - InitializingBean.afterPropertiesSet()
   - @PostConstruct
   - 自定義 init-method
8. BeanPostProcessor.postProcessAfterInitialization()  // 代理生成、AOP 織入點
9. Bean 就緒,可被注入其他 Bean / 獲取使用
10. 容器關閉 → 銷毀回調:
    - DisposableBean.destroy()
    - @PreDestroy
    - 自定義 destroy-method

各階段核心接口與執行順序

階段接口/註解典型用途順序
BeanDefinition 修改BeanFactoryPostProcessorPropertyPlaceholderConfigurer、ConfigurationClassPostProcessor (掃描 @Configuration)1 (最早)
實例化前InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation返回代理對象跳過默認實例化2
屬性填充前InstantiationAwareBeanPostProcessor.postProcessPropertyValues修改/驗證注入值3
屬性填充後——4
Aware 回調BeanNameAware / BeanFactoryAware / ApplicationContextAware 等獲取容器上下文資源5
初始化前BeanPostProcessor.postProcessBeforeInitialization初始化前增強、驗證6
初始化InitializingBean / @PostConstruct / init-method資源獲取、連接池啟動、緩存預熱7
初始化後BeanPostProcessor.postProcessAfterInitialization**AOP 代理創建**、對象包裝8 (關鍵)
銷毀DisposableBean / @PreDestroy / destroy-method資源釋放、連接關閉容器關閉時

代碼演示:完整生命周期 Bean

@Component
public class LifecycleBean implements 
        BeanNameAware, BeanFactoryAware, ApplicationContextAware,
        InitializingBean, DisposableBean {

    @PostConstruct
    public void postConstruct() { log.info("@PostConstruct"); }

    @PreDestroy
    public void preDestroy() { log.info("@PreDestroy"); }

    @Override public void setBeanName(String name) { log.info("BeanNameAware: {}", name); }
    @Override public void setBeanFactory(BeanFactory bf) { log.info("BeanFactoryAware"); }
    @Override public void setApplicationContext(ApplicationContext ctx) { log.info("ApplicationContextAware"); }
    @Override public void afterPropertiesSet() { log.info("InitializingBean"); }
    @Override public void destroy() { log.info("DisposableBean"); }

    // XML init-method/destroy-method 同理
}

後置處理器實戰:自動為所有 Service 注入請求上下文

@Component
public class RequestContextInjector implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if (bean instanceof BaseService) {
            ((BaseService) bean).setRequestContextHolder(RequestContextHolder.currentRequestAttributes());
        }
        return bean;
    }
}

工廠後置處理器實戰:動態註冊 Bean

@Component
public class DynamicBeanRegistrar implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) {
        // 運行時根據條件註冊 BeanDefinition
        if (someCondition()) {
            GenericBeanDefinition bd = new GenericBeanDefinition();
            bd.setBeanClass(DynamicService.class);
            bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
            bf.registerBeanDefinition("dynamicService", bd);
        }
    }
}

常見誤區與避坑

  1. @PostConstruct vs afterPropertiesSet:@PostConstruct 先執行(JSR-250 規範),建議統一用 @PostConstruct。
  2. 構造器注入的 Bean 在構造器中不可用其他 Bean 的生命周期方法:因循環依賴提前暴露的是早期引用,尚未初始化完成。
  3. BeanPostProcessor 返回 null:會導致後續處理器收到 null,最終 Bean 為 null,**必須返回原對象或代理對象**。
  4. 原型 Bean 銷毀不由容器管理:容器不跟蹤 prototype,需自行調用 destroy() 或用 @Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS) 配合自定義銷毀邏輯。
  5. AOP 代理在 postProcessAfterInitialization 創建:因此在 InitializingBean / @PostConstruct 中 **無法調用同類的其他 @Transactional 方法**(調用的是 this 而非代理)。

Spring Boot 2.3+ 應用上下文關閉鉤子

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(App.class, args);
        // 註冊關閉鉤子,確保 destroy-method/@PreDestroy 執行
        ctx.registerShutdownHook(); 
    }
}

總結

Spring Bean 生命周期是 **「實例化 → 填充 → Aware → 初始化(前/後置處理器環繞) → 就緒 → 銷毀」** 的標準化流程。掌握 **各階段執行順序、Aware 接口用途、BeanPostProcessor 代理生成時機、原型 Bean 銷毀責任**,即可精準控制 Bean 行為、排查循環依賴、實現框架級擴展。

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