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

深度解析 Spring 框架核心架構:從 BeanFactory 到 ApplicationContext 的演進之路

     編輯:Java 相關知識

Spring 框架的誕生背景

在 Java 企業級開發的早期,開發者面臨著極其混亂的局面:EJB(Enterprise JavaBeans)過於笨重、配置複雜,且難以進行單元測試。正是在這樣的背景下,Rod Johnson 撰寫了《Expert One-on-One J2EE Design and Development》一書,並發布了隨書附贈的框架代碼——這就是 Spring 框架的雛形。Johnson 堅信「面向介面編程」能將變更控制在最小範圍,同時便於擴展與維護,這一設計哲學貫穿了 Spring 的整個架構體系。

核心容器體系的層層抽象

BeanFactory:IoC 容器的基石

所有對象的「母親」——BeanFactory,是 Spring IoC 容器的最核心接口。它定義了獲取 Bean、管理 Bean 生命週期的基本規範。有了它,我們就能獲得容器中所有被管理的對象及其屬性。

ListableBeanFactory 與 HierarchicalBeanFactory:擴展容器能力

隨著需求增長,Johnson 發現單純的 BeanFactory 不夠用:

  • ListableBeanFactory:支持批量獲取同類型 Bean(如 getBeansOfType),不再局限於單個實例獲取;
  • HierarchicalBeanFactory:引入父子容器層級結構(如 getParentBeanFactory),為 Web 應用中的上下文隔離奠定基礎。

ApplicationContext:賦予容器「應用級」能力

BeanFactory 只關注 Bean 本身,但實際應用中還需要:應用名稱、啟動時間、國際化訊息、事件發布、資源加載、環境感知等能力。因此誕生了 ApplicationContext,它繼承並整合了以下關鍵介面:

  • MessageSource:國際化訊息解析;
  • ApplicationEventPublisher:事件發布機制,實現組件解耦;
  • ResourcePatternResolver:統一資源加載策略;
  • EnvironmentCapable:環境感知與配置管理。

可配置與 Web 專用擴展

為了支持運行時配置修改,引入了 ConfigurableBeanFactory 和 ConfigurableApplicationContext;針對 Web 場景強依賴 ServletContext,提供了 WebApplicationContext。

從介面到實現:DefaultListableBeanFactory 的誕生

Johnson 並未止步於介面設計,而是著手構建真正可運行的實現類。他創建了 ConfigurableListableBeanFactory,整合了 AutowireCapableBeanFactory、ListableBeanFactory、ConfigurableBeanFactory 三大能力。同時,將 Bean 的別名註冊(SimpleAliasRegistry)、單例緩存(DefaultSingletonBeanRegistry)、FactoryBean 註冊(FactoryBeanRegistrySupport)等核心功能模組化實現。

最終誕生的 DefaultListableBeanFactory,是 Spring 所有 IoC 容器的「始祖」。它不僅是第一個真正可用的 BeanFactory 實現,更成為了獨立構建 IoC 容器的基礎——後續擴展多基於繼承或組合它。

ClassPathResource res = new ClassPathResource("applicationContext.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(res);

ApplicationContext 的三大經典實現

有了強大的 BeanFactory,Johnson 接著構建了三個核心 ApplicationContext 實現:

  • FileSystemXmlApplicationContext:從文件系統加載 XML 配置;
  • ClassPathXmlApplicationContext:從類路徑加載 XML 配置;
  • AnnotationConfigWebApplicationContext:從註解掃描加載 Bean,開啟了「零配置」時代。

統一啟動流程:AbstractApplicationContext 的藝術

Johnson 將啟動流程抽象到 AbstractApplicationContext 中,實現了 ConfigurableApplicationContext,並整合了 DefaultResourceLoader 統一資源加載。核心啟動邏輯封裝在 refresh() 方法中:

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        prepareRefresh();                    // 1. 準備刷新:日誌、屬性驗證
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 2. 獲取新 BeanFactory
        prepareBeanFactory(beanFactory);     // 3. 配置 BeanFactory 基礎屬性
        
        try {
            postProcessBeanFactory(beanFactory);           // 4. 子類後處理
            invokeBeanFactoryPostProcessors(beanFactory);  // 5. BeanFactoryPostProcessor
            registerBeanPostProcessors(beanFactory);       // 6. 註冊 BeanPostProcessor
            initMessageSource();                           // 7. 初始化訊息源
            initApplicationEventMulticaster();             // 8. 初始化事件廣播器
            onRefresh();                                   // 9. 子類擴展點
            registerListeners();                           // 10. 註冊監聽器
            finishBeanFactoryInitialization(beanFactory);  // 11. 實例化非懶加載單例
            finishRefresh();                               // 12. 發布完成事件
        } catch (BeansException ex) {
            destroyBeans();           // 回滾:銷毀已創建單例
            cancelRefresh(ex);        // 重置狀態
            throw ex;                 // 拋出異常
        }
    }
}

啟動流程的五大核心維度

  1. 刷新生命週期:prepareRefresh、onRefresh、finishRefresh、cancelRefresh;
  2. BeanFactory 初始化與準備:銷舊建新、加載 BeanDefinition;
  3. BeanDefinition 生成與註冊:XML 解析、registerBeanDefinition 回調至 DefaultListableBeanFactory;
  4. BeanFactory 後處理器:postProcessBeanFactory、invokeBeanFactoryPostProcessors、registerBeanPostProcessors;
  5. 訊息、事件與監聽器裝配:DelegatingMessageSource、SimpleApplicationEventMulticaster、應用監聽器註冊。

Spring 事件機制:解耦的藝術

事件機制是 Spring 核心容器內建的解耦利器:

  • 發布者:ApplicationContext 實現 ApplicationEventPublisher;
  • 監聽器集合:applicationListeners;
  • 廣播器:ApplicationEventMulticaster 負責分發。

流程:addApplicationListener 註冊 → publishEvent 遍歷調用 onApplicationEvent → 遞歸向父上下文廣播。框架內部大量使用:ContextRefreshedEvent、ContextStartedEvent、ContextStoppedEvent 等。

三大擴展機制:讓框架更柔軟

1. BeanPostProcessor:Bean 生命週期攔截器

在 Bean 初始化前(postProcessBeforeInitialization)和初始化後(postProcessAfterInitialization)插入自定義邏輯。典型應用:ApplicationContextAwareProcessor 自動注入各類 Aware 介面(BeanNameAware、ApplicationContextAware 等)。

private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof EnvironmentAware) 
            ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
        if (bean instanceof ApplicationContextAware) 
            ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
        // ... 其他 Aware 介面處理
    }
}

2. Aware 機制:讓 Bean 感知容器

實現特定 Aware 子介面,容器自動回調注入相關資源:

public class HelloBean implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    public void setApplicationContext(ApplicationContext context) {
        this.applicationContext = context;
    }
    public String getHelloWord() {
        applicationContext.publishEvent(new PropertyGettedEvent("[" + helloWord + "] is getted"));
        return helloWord;
    }
}

3. BeanFactoryPostProcessor:容器級擴展

在 BeanFactory 創建完、Bean 實例化前介入,可修改 BeanDefinition。例:統計 Bean 定義數量。

public class BeanCounter implements BeanFactoryPostProcessor {
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        System.out.println(beanFactory.getBeanDefinitionCount());
    }
}

4. FactoryBean:工廠模式的極致應用

FactoryBean 是一種特殊 Bean,它本身是 Bean,又能生產真實 Bean。AbstractBeanFactory.getObjectForBeanInstance 負責識別並處理:普通 Bean 直接返回,FactoryBean 則調用 getObject() 獲取真實對象。典型案例:LocalSessionFactoryBean 封裝 Hibernate SessionFactory 複雜創建邏輯。

protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
        return beanInstance; // 普通 Bean 或強制獲取工廠本身
    }
    FactoryBean factory = (FactoryBean) beanInstance;
    return getObjectFromFactoryBean(factory, beanName, !synthetic); // 委託工廠生產
}

總結

Spring 框架的核心架構,是一個從「介面設計」到「實現落地」、從「核心容器」到「擴展機制」層層遞進、環環相扣的精密體系。Rod Johnson 以面向介面編程為指導思想,構建了 BeanFactory 為根、ApplicationContext 為幹、三大擴展機制為枝葉的宏大架構。理解這條主線,不僅能讀懂 Spring 源碼,更能在實戰中靈活運用其擴展點,打造高內聚、低耦合的企業級應用。

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