Spring 框架雖擁有十幾個模組,但真正的核心僅三個:Core、Context 與 Beans。這三者構建了 Spring 的骨幹,支撐起 AOP、Web 等上層功能。若將 Spring 比作一場戲劇:Bean 是演員,Context 是舞臺背景,Core 則是道具——三者缺一不可。
Spring 的核心設計目標是解決物件間的依賴關係,透過 IoC 容器將依賴關係外部化到配置檔中管理。Bean 就像 OOP 中的 Object,是 Spring 世界的主角。Spring 將物件包裝在 Bean 中,以便統一管理並提供額外服務(如生命週期、AOP 代理等)。這種策略類似 Java 實現 OOP 的方式:建構數據結構、定義生存環境、規範交互規則。
Bean 組件位於 org.springframework.beans,解決 Bean 定義、創建、解析三大問題。其創建機制採用工廠模式,頂層介面為 BeanFactory,默認實現為 DefaultListableBeanFactory,實作了多個子介面:
ListableBeanFactory:可列舉 BeanHierarchicalBeanFactory:支援父子層級關係AutowireCapableBeanFactory:定義自動裝配規則這些介面劃分職責,限制內部操作時的數據訪問權限。Bean 定義由 BeanDefinition 描述,對應 XML 中的 <bean/> 節點。解析過程極其複雜,涉及大量擴展點以應對變化。
Context 位於 org.springframework.context,提供運行時環境,維護 Bean 關係集合(即 IoC 容器)。頂層介面 ApplicationContext 繼承 BeanFactory 與 ResourceLoader,可訪問外部資源。主要子類包括:
ConfigurableApplicationContext:可動態修改配置WebApplicationContext:Web 環境專用,可訪問 ServletContextContext 整合了 Spring 大部分功能,是 IoC 容器的核心載體。
Core 封裝了資源訪問方式,將所有資源抽象為 Resource 介面,屏蔽檔案類型差異。ResourceLoader 統一資源加載,默認實現 DefaultResourceLoader。Context 委託 ResourcePatternResolver 整合資源加載、解析與定義,體現「中介者」模式。
容器構建入口在 AbstractApplicationContext.refresh(),主要步驟:
BeanFactory(obtainFreshBeanFactory)finishBeanFactoryInitialization)refreshBeanFactory() 中會銷毀舊工廠、創建 DefaultListableBeanFactory、載入 Bean 定義。載入過程涉及 XML 解析、BeanDefinition 註冊等時序流程。
單例 Bean 實例化在 DefaultListableBeanFactory.preInstantiateSingletons() 中進行。關鍵點是 FactoryBean:一種特殊 Bean,其 getObject() 返回真實物件,為 Spring 提供極大擴展性。普通 Bean 透過 getBean() 創建,過程涉及實例化、屬性填充、初始化、後處理等階段。依賴關係建立在屬性填充階段完成,透過解析 ref、autowire 等配置實現。
| 擴展點 | 觸發時機 | 用途 |
|---|---|---|
| BeanFactoryPostProcessor | BeanFactory 構建後 | 修改 Bean 定義元數據 |
| BeanPostProcessor | Bean 實例化前後 | 自定義初始化/代理邏輯 |
| InitializingBean / DisposableBean | Bean 初始化/銷毀 | 生命週期回調 |
| FactoryBean | 獲取 Bean 實例時 | 完全自定義物件創建 |
這些擴展點是 Spring 功能可定制化的關鍵,AOP 即通過實現擴展點達成。
AOP 基於動態代理。JDK java.lang.reflect.Proxy 透過 newProxyInstance(loader, interfaces, handler) 生成代理類,實現目標介面並持有 InvocationHandler。調用代理方法會轉發至 invoke()。代理類結構示例:
public class $Proxy2 extends java.lang.reflect.Proxy implements SimpleProxy {
java.lang.reflect.Method m0, m1, m2, m3, m4;
// hashCode, equals, toString, simpleMethod1, simpleMethod2...
}
每個方法對應一個 Method 屬性,調用時傳遞給 invoke()。
Spring 透過 ProxyFactoryBean(實現 FactoryBean)創建代理。配置需指定 proxyInterfaces、target、interceptorNames。代理生成時序涉及 JdkDynamicAopProxy 實現 InvocationHandler,調用攔截器鏈(MethodInterceptor)。Spring 也支援 CGLIB 類代理(針對無介面類)。
Spring AOP 是代理模式的經典應用。$Proxy 實現目標介面、SpringProxy、Advised,透過 InvocationHandler 持有目標引用。真實代理類結構包含大量 Method 屬性與介面方法。
代理策略選擇(JDK vs CGLIB)採用策略模式:AopProxy 為抽象策略,JdkDynamicAopProxy、Cglib2AopProxy 為具體實現。ProxyFactoryBean 作為 Context,根據條件(目標是否有介面、配置)選擇策略,調用 getProxy() 完成創建。
Spring 透過抽象複雜物件、規範標準、構建容器管理關係,展現了極佳的框架設計智慧。其核心思想——「抽象變化點、封裝不變點、提供擴展機制」——對軟體架構設計極具參考價值。深入源碼仍是掌握精髓的最佳途徑。