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

Spring IOC 容器核心源碼深度解析:從 BeanFactory 到 ApplicationContext 的完整初始化鏈路

     編輯:Java 相關知識

IOC 容器的兩張面孔:BeanFactory vs ApplicationContext

維度BeanFactoryApplicationContext
定位IOC 核心接口,最小化功能集企業級應用上下文,功能豐富
核心能力getBean、containsBean、isSingleton、getType、getAliases繼承 BeanFactory + MessageSource + ResourceLoader + ApplicationEventPublisher + 父子上下文
初始化時機延遲加載(調用 getBean 時)啟動即刷新(預實例化單例)
典型實現XmlBeanFactory、DefaultListableBeanFactoryClassPathXmlApplicationContext、FileSystemXmlApplicationContext、AnnotationConfigApplicationContext
適用場景資源受限、測試、嵌入式生產環境標準選擇

BeanFactory 體系:DefaultListableBeanFactory 為核心實現

DefaultListableBeanFactory 實現了 ConfigurableListableBeanFactory、BeanDefinitionRegistry、Serializable 等接口,是 Bean 註冊表、依賴解析引擎、作用域管理器 的集大成者。

XmlBeanFactory:最基礎的 XML 驅動容器(已過時,教學用)

public class XmlBeanFactory extends DefaultListableBeanFactory {
    private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
    
    public XmlBeanFactory(Resource resource) throws BeansException {
        this(resource, null);
    }
    public XmlBeanFactory(Resource resource, BeanFactory parent) throws BeansException {
        super(parent);
        this.reader.loadBeanDefinitions(resource); // 關鍵:載入 BeanDefinition
    }
}

缺點:不支援國際化、事件發布、資源加載、Web 整合、生命週期回調等企業級特性。

ApplicationContext 初始化模板:AbstractApplicationContext.refresh()

所有 ApplicationContext 實現均繼承 AbstractApplicationContext,核心初始化邏輯在 refresh():

public void refresh() throws BeansException, IllegalStateException {
    synchronized (startupShutdownMonitor) {
        // 1. 準備上下文環境
        prepareRefresh();
        
        // 2. 獲取/創建 BeanFactory(子類實現)
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        
        // 3. 配置 BeanFactory 標準化
        prepareBeanFactory(beanFactory);
        
        // 4. 子類擴展點:後處理 BeanFactory
        postProcessBeanFactory(beanFactory);
        
        // 5. 調用 BeanFactoryPostProcessor(如 PropertyPlaceholderConfigurer)
        invokeBeanFactoryPostProcessors(beanFactory);
        
        // 6. 註冊 BeanPostProcessor(如 AutowiredAnnotationBeanPostProcessor)
        registerBeanPostProcessors(beanFactory);
        
        // 7. 初始化 MessageSource、事件廣播器等
        initMessageSource();
        initApplicationEventMulticaster();
        
        // 8. 子類擴展點:初始化特定 Bean(如 DispatcherServlet 初始化 MVC 組件)
        onRefresh();
        
        // 9. 註冊監聽器
        registerListeners();
        
        // 10. 實例化所有非懶加載單例 Bean(核心階段)
        finishBeanFactoryInitialization(beanFactory);
        
        // 11. 發布 ContextRefreshedEvent,完成刷新
        finishRefresh();
    }
}

關鍵子類實現:obtainFreshBeanFactory()

  • AbstractRefreshableApplicationContext:創建 DefaultListableBeanFactory,設置序列化 ID、BeanClassLoader、表達式解析器等。
  • AbstractXmlApplicationContext:在 loadBeanDefinitions() 中使用 XmlBeanDefinitionReader 解析 XML。
  • ClassPathXmlApplicationContext:構造函數接收 configLocations,getConfigResources() 解析為 ClassPathResource[]。
  • FileSystemXmlApplicationContext:getResourceByPath() 返回 FileSystemResource。

BeanDefinition 載入與註冊全流程

資源定位:ResourceLoader 體系

public interface ResourceLoader {
    Resource getResource(String location); // 支援 classpath:、file:、http:、相對路徑
}
  • ClassPathResource:類路徑資源。
  • FileSystemResource:文件系統絕對/相對路徑。
  • UrlResource:HTTP/FTP/JAR 等 URL。
  • ServletContextResource:Web 應用 /WEB-INF/ 資源。

上下文實現 ResourceLoader,委託給內部 DefaultResourceLoader 或子類重寫 getResourceByPath()。

XML 解析:XmlBeanDefinitionReader → DocumentLoader → BeanDefinitionDocumentReader

  1. loadBeanDefinitions(Resource) → InputStream → InputSource。
  2. doLoadBeanDefinitions():DocumentBuilderFactory 解析 DOM。
  3. registerBeanDefinitions(Document):委託 BeanDefinitionDocumentReader(默認 DefaultBeanDefinitionDocumentReader)。

DefaultBeanDefinitionDocumentReader 解析邏輯

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    Element root = doc.getDocumentElement();
    BeanDefinitionParserDelegate delegate = createHelper(readerContext, root);
    preProcessXml(root);
    parseBeanDefinitions(root, delegate); // 核心遞歸解析
    postProcessXml(root);
}

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    NodeList nl = root.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
        Node node = nl.item(i);
        if (node instanceof Element) {
            Element ele = (Element) node;
            if (delegate.isDefaultNamespace(ele.getNamespaceURI())) {
                parseDefaultElement(ele, delegate); // 、、
            } else {
                delegate.parseCustomElement(ele); // 、、 等擴展命名空間
            }
        }
    }
}

元素解析:BeanDefinitionParserDelegate.parseBeanDefinitionElement()

解析屬性:id/name、class、scope、lazy-init、autowire、depends-on、init-method/destroy-method、factory-bean/factory-method、constructor-arg、property、lookup-method/replaced-method、meta、qualifier。

生成 BeanDefinitionHolder(包含 BeanName、BeanDefinition、Aliases),調用 BeanDefinitionReaderUtils.registerBeanDefinition() 註冊到 BeanDefinitionRegistry(即 DefaultListableBeanFactory.beanDefinitionMap)。

Bean 實例化與依賴注入:核心流程

getBean() 觸發創建

public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

protected  T doGetBean(String name, Class requiredType, Object[] args, boolean typeCheckOnly) {
    // 1. 轉換別名、工廠前綴(&)
    String beanName = transformedBeanName(name);
    
    // 2. 檢查單例緩存
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null) return getObjectForBeanInstance(sharedInstance, name, beanName, null);
    
    // 3. 原型/其他作用域:創建新實例
    if (isPrototypeCurrentlyInCreation(beanName)) throw new BeanCurrentlyInCreationException(beanName);
    
    // 4. 父子上下文委派
    BeanFactory parent = getParentBeanFactory();
    if (parent != null && !containsBeanDefinition(beanName)) {
        return (parent instanceof ApplicationContext) 
            ? ((ApplicationContext) parent).getBean(name) 
            : parent.getBean(name);
    }
    
    // 5. 合併 BeanDefinition(父 Bean 覆蓋)
    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    
    // 6. 檢查 depends-on
    String[] dependsOn = mbd.getDependsOn();
    if (dependsOn != null) for (String dep : dependsOn) getBean(dep);
    
    // 7. 實例化
    if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, () -> createBean(beanName, mbd, args));
        return getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    } else if (mbd.isPrototype()) {
        return getObjectForBeanInstance(createBean(beanName, mbd, args), name, beanName, mbd);
    } else {
        // 自定義 Scope
        Scope scope = scopes.get(mbd.getScope());
        return scope.get(beanName, () -> createBean(beanName, mbd, args));
    }
}

createBean() 實例化流程

  1. 實例化前:resolveBeforeInstantiation() → InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()(可返回代理對象,跳過默認實例化)。
  2. 實例化:createBeanInstance() → 構造函數注入 / 工廠方法 / 默認無參構造(通過反射或 CGLIB FastClass)。
  3. 屬性填充:populateBean() → 解析 property/constructor-arg → 類型轉換 → AutowiredAnnotationBeanPostProcessor 處理 @Autowired/@Value → InstantiationAwareBeanPostProcessor.postProcessProperties()。
  4. 初始化:initializeBean() →
    1. Aware 接口回調(BeanNameAware、BeanFactoryAware、ApplicationContextAware 等)。
    2. BeanPostProcessor.postProcessBeforeInitialization()。
    3. 調用 init-method / InitializingBean.afterPropertiesSet() / @PostConstruct。
    4. BeanPostProcessor.postProcessAfterInitialization()(AOP 代理在此生成)。
  5. 註冊銷毀回調:單例 Bean 註冊 DisposableBean/destroy-method/@PreDestroy 到 singletonFactories。

擴展點總結:BeanPostProcessor vs BeanFactoryPostProcessor

接口調用時機典型實現作用
BeanFactoryPostProcessorBeanDefinition 載入後、Bean 實例化前PropertyPlaceholderConfigurer、ConfigurationClassPostProcessor修改 BeanDefinition 元數據(佔位符解析、掃描 @Configuration 類)
BeanPostProcessorBean 實例化前後、初始化前後AutowiredAnnotationBeanPostProcessor、AnnotationAwareAspectJAutoProxyCreator修改 Bean 實例(依賴注入、AOP 代理、初始化增強)

事件機制:ApplicationEventPublisher + ApplicationListener

  • 內建事件:ContextRefreshedEvent、ContextClosedEvent、RequestHandledEvent。
  • 自定義事件:實現 ApplicationEvent,發布 applicationContext.publishEvent(event),監聽器實現 ApplicationListener<E> 或 @EventListener。
  • 異步事件:@Async @EventListener 或配置 ApplicationEventMulticaster 使用 TaskExecutor。

總結

Spring IOC 容器的初始化是一條精心設計的流水線:

  1. 資源定位:ResourceLoader 抽象多種資源來源。
  2. 元數據解析:BeanDefinitionReader + DocumentReader 將 XML/註解轉為 BeanDefinition。
  3. 註冊表構建:DefaultListableBeanFactory.beanDefinitionMap 持有所有 Bean 元數據。
  4. 後處理增強:BeanFactoryPostProcessor 修改元數據,BeanPostProcessor 操作實例。
  5. 實例化注入:構造函數/Setter/字段注入,類型轉換,循環依賴處理(三級緩存)。
  6. 生命週期管理:初始化回調、AOP 代理生成、銷毀回調註冊。
  7. 上下文功能:國際化、事件發布、資源加載、父子委派。

掌握這條主線,配合 BeanPostProcessor 擴展點,你就掌握了 Spring 容器的靈魂——在不修改框架代碼的前提下,通過標準化 SPI 接口實現無限擴展。

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