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

Spring 源碼學習:IOC 容器初始化流程深度解析(二)——ApplicationContext 體系與 refresh() 全過程

     編輯:Java 綜合教學

Spring 源碼學習:IOC 容器初始化流程深度解析(二)

一、Spring 三大核心組件協作

  • Bean:包裝用戶對象,解決定義、創建、解析。
  • Core:資源抽象(Resource、ResourceLoader)、工具支撐。
  • Context:提供運行時環境,維護 Bean 關系,即 IOC 容器(ApplicationContext)。

二、ApplicationContext 繼承體系

ApplicationContext
  ├─ EnvironmentCapable
  ├─ ListableBeanFactory
  ├─ HierarchicalBeanFactory
  ├─ MessageSource          # 國際化
  ├─ ApplicationEventPublisher # 事件發布
  └─ ResourcePatternResolver # 資源加載
常用實現:ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、XmlWebApplicationContext

三、refresh() 核心流程(AbstractApplicationContext)

public void refresh() {
    synchronized (startupShutdownMonitor) {
        prepareRefresh();                    // 1. 記錄啟動時間、active 標誌
        ConfigurableListableBeanFactory bf = obtainFreshBeanFactory(); // 2. 創建/刷新 BeanFactory
        prepareBeanFactory(bf);              // 3. 配置工廠(ClassLoader、SpEL、編輯器、AwareProcessor)
        postProcessBeanFactory(bf);          // 4. 子類擴展點
        invokeBeanFactoryPostProcessors(bf); // 5. 執行 BeanFactoryPostProcessor
        registerBeanPostProcessors(bf);      // 6. 註冊 BeanPostProcessor
        initMessageSource();                 // 7. 國際化
        initApplicationEventMulticaster();   // 8. 事件廣播器
        onRefresh();                         // 9. 子類特殊 Bean 初始化
        registerListeners();                 // 10. 註冊 ApplicationListener
        finishBeanFactoryInitialization(bf); // 11. 預實例化非懶加載單例
        finishRefresh();                     // 12. 發布 ContextRefreshedEvent
    }
}

關鍵步驟深度剖析

2. obtainFreshBeanFactory() → refreshBeanFactory()

  • 銷毀舊工廠 → createBeanFactory() 創建 DefaultListableBeanFactory。
  • customizeBeanFactory() 設置序列化 ID、允許 Bean 覆蓋等。
  • loadBeanDefinitions() 委派 XmlBeanDefinitionReader 解析 XML → BeanDefinition 註冊到註冊表。

11. finishBeanFactoryInitialization() → preInstantiateSingletons()

for (String beanName : beanDefinitionNames) {
    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
        if (isFactoryBean(beanName)) {
            FactoryBean factory = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (factory instanceof SmartFactoryBean && factory.isEagerInit()) getBean(beanName);
        } else {
            getBean(beanName); // 觸發完整創建流程
        }
    }
}
// 回調 SmartInitializingSingleton.afterSingletonsInstantiated()

擴展點總結

接口調用時機典型用途
BeanFactoryPostProcessorBeanDefinition 註冊後、實例化前PropertyPlaceholderConfigurer、ConfigurationClassPostProcessor
BeanPostProcessor實例化前後(populate 後、init 前/後)AutowiredAnnotationProcessor、AOP 代理創建
InitializingBean / @PostConstruct屬性注入完成後自定義初始化邏輯
DisposableBean / @PreDestroy容器關閉前資源釋放

調試建議

  1. 在 prepareRefresh()、obtainFreshBeanFactory()、preInstantiateSingletons() 打斷點觀察 BeanDefinition 註冊與單例創建過程。
  2. 關注 beanFactoryMonitor 鎖與 startupShutdownMonitor 鎖的並發控制。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved