1. 程式人生 > 實用技巧 >20201128 IoC容器設計實現及Spring原始碼分析 - 拉勾教育

20201128 IoC容器設計實現及Spring原始碼分析 - 拉勾教育

環境資訊

  • Spring 版本:5.1.12.RELEASE

第一部分 Spring 概述

Spring 是分層的 full-stack(全棧) 輕量級開源框架,以 IoC 和 AOP 為核心,提供了展現層 Spring
MVC 和業務層事務管理等眾多的企業級應用技術,還能整合開源世界眾多著名的第三方框架和類庫,已
經成為使用最多的 Java EE 企業應用開源框架。

第二部分 核心思想

IoC

  • IoC:Inversion of Control (控制反轉/反轉控制),注意它是⼀個 技術思想,不是一個技術實現

    • 使用 IoC 讓我們喪失了⼀個權利(建立、管理物件的權利),得到了⼀個福利(不用考慮物件的建立、管理等⼀系列事情)
  • IoC 解決物件之間的耦合問題,物件之間不再相互依賴,而是依賴於 IoC 容器

IoC 和 DI 的區別

  • DI: Dependancy Injection(依賴注入)
  • IoC 和 DI 描述的是同一件事情(物件例項化及依賴關係維護),只不過角度不同罷了
  • IoC 是站在物件的角度,物件例項化及其管理的權利交給了(反轉)給了容器
  • DI 是站在容器的角度,容器會把物件依賴的其他物件注入(送進去),比如 A 物件例項化過程中因為聲明瞭一個 B 型別的屬性,那麼就需要容器把 B 物件注入給 A

AOP

  • AOP:Aspect oriented Programming 面向切面程式設計/面向方面程式設計

  • AOP 是 OOP 的延續、補充

  • OOP 三大特徵:封裝、繼承和多型

  • OOP 是一種垂直繼承體系

  • AOP 在解決什麼問題

    • 在不改變原有業務邏輯情況下,增強橫切邏輯程式碼,根本上解耦合,避免橫切邏輯程式碼重複
  • 橫切邏輯

  • AOP 獨闢蹊徑提出橫向抽取機制,將橫切邏輯程式碼和業務邏輯程式碼分析

第三部分 手寫實現 IoC 和 AOP

第四部分 Spring IOC 應用

第五部分 Spring IOC 原始碼深度剖析

Spring IoC 迴圈依賴問題

相關程式碼

xml 配置:

	<!--迴圈依賴問題-->
	<bean id="lagouBean" class="com.lagou.edu.LagouBean">
		<property name="ItBean" ref="itBean"/>
	</bean>
	<bean id="itBean" class="com.lagou.edu.ItBean">
		<property name="LagouBean" ref="lagouBean"/>
	</bean>

Java 程式碼:

	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    LagouBean lagouBean = applicationContext.getBean(LagouBean.class);
    System.out.println(lagouBean);

如上可知:

  • lagouBean 和 itBean 互為依賴
  • Spring 按照配置順序載入 Bean,所以先載入 lagouBean

UML 圖說明

首先,Spring 為解決迴圈依賴,使用了三級快取:

  1. DefaultSingletonBeanRegistry#singletonObjects
    • 賦值方法:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton
  2. DefaultSingletonBeanRegistry#earlySingletonObjects
    • 賦值方法:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
  3. DefaultSingletonBeanRegistry#singletonFactories
    • 賦值方法:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory

從三級快取中獲取值的方法為:

  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)

Spring 載入兩個互為依賴的 Bean 整體流程如 UML 圖,圖中說明如下:

  • 整體流程為:
    1. doGetBean 方法獲取 lagouBean
    2. getSingleton 方法從三級快取中獲取 lagouBean,未獲取到
    3. doCreateBean 方法、createBeanInstance 方法建立 lagouBean 例項
    4. addSingletonFactory 方法將 lagouBean 加入第三級快取 singletonFactories
    5. populateBean 方法為 lagouBean 屬性賦值時通過 doGetBean 方法觸發 itBean 的建立
      1. doGetBean 方法獲取 itBean
      2. getSingleton 方法從三級快取中獲取 itBean ,未獲取到
      3. doCreateBean 方法、createBeanInstance 方法建立 itBean 例項
      4. addSingletonFactory 方法將 itBean 加入第三級快取 singletonFactories
      5. populateBean 方法為 itBean 屬性賦值時通過 doGetBean 方法從快取中獲取 lagouBean
        1. getSingleton 方法從三級快取中獲取 lagouBean,獲取到,存入二級快取 earlySingletonObjects,並從三級快取 singletonFactories 中刪除 lagouBean
      6. itBean 建立完成,addSingleton 將 itBean 加入一級快取,並從二、三級快取中刪除(此時,itBean 在三級快取,lagouBean 在二級快取)
    6. lagouBean 建立完成,addSingleton 將 lagouBean 加入一級快取,並從二、三級快取中刪除

第六部分 Spring AOP 應用

  • AOP本質:在不改變原有業務邏輯的情況下增強橫切邏輯,橫切邏輯程式碼往往是許可權校驗程式碼、日誌程式碼、事務控制程式碼、效能監控程式碼。

第七部分 Spring AOP原始碼深度剖析

參考資料