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

Spring 容器核心原理深度解析:IOC/AOP/啟動流程/Bean生命周期/事件機制

     編輯:Java 綜合教學

一、IOC(控制反轉)核心思想

從「主動獲取」到「被動接收」

  • 傳統模式:對象 A 需要 B → A 內部 new B() 或 JNDI 查找 → A 與 B 緊耦合,生命周期由 A 控制
  • Spring IOC:所有對象註冊到容器 → 聲明依賴關系 → 容器啟動時構建對象圖 → 依賴注入 (DI) 將 B「打針」進 A

控制權轉移

對象創建、銷毀、依賴綁定 控制權從業務代碼轉移到 Spring 容器,實現低耦合、高內聚、易測試、易擴展。

二、IOC 三大注入方式對比

方式特點優勢劣勢推薦度
接口注入實現特定接口標準化侵入性強、靈活性差❌ Spring 不支持
Setter 注入setXxx() 方法可讀性強、支持可選依賴、循環依賴友好對象構建過程中可能處於不完整狀態★★★★☆
構造器注入構造函數參數構造期即完整、依賴不可變、強制依賴明確參數過多時構造函數膨脹、循環依賴難處理★★★★★

最佳實踐:強制依賴用構造器注入,可選依賴用 Setter 注入(Spring 4.0+ 推薦)。

三、AOP(面向切面編程)核心概念

解決什麼問題?

橫切關注點:日誌、事務、安全、異常處理……分散在各業務模塊,導致代碼重復、耦合度高。

核心術語

術語含義Spring 實現
Aspect (切面)橫切邏輯模塊化@Aspect + Advisor/Interceptor
Joinpoint (連接點)程序執行具體點(方法調用、異常拋出)方法執行
Advice (通知)切面在連接點執行的動作Before/After/AfterReturning/AfterThrowing/Around
Pointcut (切入點)匹配連接點的表達式@Pointcut、正則、AspectJ 表達式
Target (目標對象)被代理的業務對象POJO
Proxy (代理)織入切面後的代理對象JDK Dynamic Proxy / CGLIB
Weaving (織入)將切面應用到目標對象運行時動態織入

五大通知類型

  • @Before:方法前執行(不可阻止執行)
  • @AfterReturning:正常返回後執行
  • @Around:環繞全過程,可控制是否執行目標方法、修改參數/返回值(最強大)
  • @AfterThrowing:拋出異常後執行
  • @After:最終執行(類似 finally)

四、Spring 容器啟動核心流程

入口:new ClassPathXmlApplicationContext("applicationContext.xml") → AbstractApplicationContext.refresh()

關鍵步驟

  1. prepareRefresh():載入配置、驗證必填項
  2. obtainFreshBeanFactory():
    • 銷毀舊容器(重啟場景)
    • 創建 DefaultListableBeanFactory
    • 設置序列化 ID、允許 Bean 覆蓋/循環引用配置
    • 註冊標準註解處理器(@Autowired、@Value 等)
  3. loadBeanDefinitions():解析 XML/註解配置,註冊 BeanDefinition
    • 命名空間處理器映射
    • 標簽解析器分發
  4. finishBeanFactoryInitialization():預實例化單例 Bean
  5. finishRefresh():發布 ContextRefreshedEvent,啟動生命周期處理器

五、如何感知容器啟動完成?

實現 ApplicationListener<ContextRefreshedEvent>:

@Component
public class StartupListener implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // 容器初始化/刷新完成時觸發
        // 執行啟動後初始化任務:預熱緩存、啟動調度任務、註冊服務等
    }
}

事件廣播機制:ApplicationEventMulticaster.multicastEvent() → 遍歷所有 ApplicationListener 異步/同步調用。

六、FactoryBean vs BeanFactory

概念本質區別
BeanFactoryIOC 容器核心接口管理 Bean 定義、依賴關系、生命周期的「超級工廠」
FactoryBean特殊 Bean 類型getObject() 返回的才是真正注入的對象,而非 FactoryBean 本身

典型應用:SqlSessionFactoryBean、DataSourceFactoryBean 等封裝複雜創建邏輯。

七、Bean 生命周期全景圖

實例化 → 屬性填充 → 初始化前後置處理器 → 初始化方法 → AOP 代理 → 
放入單例池 → 使用中 → 銷毀前置處理器 → 銷毀方法 → 移出容器

關鍵擴展點

  1. InstantiationAwareBeanPostProcessor:
    • postProcessBeforeInstantiation():實例化前,返回非 null 可跳過默認創建(AOP 代理生成點)
    • postProcessAfterInstantiation():實例化後,屬性填充前
  2. BeanPostProcessor:
    • postProcessBeforeInitialization():初始化方法前
    • postProcessAfterInitialization():初始化方法後(AOP 代理包裝點)
  3. InitializingBean / @PostConstruct:初始化邏輯
  4. DisposableBean / @PreDestroy / destroy-method:銷毀邏輯

Scope 影響

  • singleton(默認):容器啟動創建,完整生命周期
  • prototype:每次 getBean() 創建,**容器不管理銷毀**(需客戶端自行清理)
  • lazy-init="true":延遲到首次獲取時創建

八、BeanFactoryPostProcessor 機制

在 Bean 實例化前修改 BeanDefinition 元數據:

  • PropertyPlaceholderConfigurer:解析 ${xxx} 佔位符
  • ConfigurationClassPostProcessor:解析 @Configuration、@ComponentScan 等註解

調用鏈:refresh() → invokeBeanFactoryPostProcessors() → 排序 → 逐個 postProcessBeanFactory()。

核心心法:Spring 容器本質是「BeanDefinition 註冊表 + 生命周期管理器 + 擴展點鏈」。掌握 BeanDefinition 元數據結構、PostProcessor 擴展機制、AOP 代理生成時機,即掌握了 Spring 的靈魂。

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