20201128 IoC容器設計實現及Spring原始碼分析 - 拉勾教育
阿新 • • 發佈:2020-11-28
環境資訊
- 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 為解決迴圈依賴,使用了三級快取:
DefaultSingletonBeanRegistry#singletonObjects
- 賦值方法:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton
- 賦值方法:
DefaultSingletonBeanRegistry#earlySingletonObjects
- 賦值方法:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
- 賦值方法:
DefaultSingletonBeanRegistry#singletonFactories
- 賦值方法:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory
- 賦值方法:
從三級快取中獲取值的方法為:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
Spring 載入兩個互為依賴的 Bean 整體流程如 UML 圖,圖中說明如下:
- 整體流程為:
- doGetBean 方法獲取 lagouBean
- getSingleton 方法從三級快取中獲取 lagouBean,未獲取到
- doCreateBean 方法、createBeanInstance 方法建立 lagouBean 例項
- addSingletonFactory 方法將 lagouBean 加入第三級快取 singletonFactories
- populateBean 方法為 lagouBean 屬性賦值時通過 doGetBean 方法觸發 itBean 的建立
- doGetBean 方法獲取 itBean
- getSingleton 方法從三級快取中獲取 itBean ,未獲取到
- doCreateBean 方法、createBeanInstance 方法建立 itBean 例項
- addSingletonFactory 方法將 itBean 加入第三級快取 singletonFactories
- populateBean 方法為 itBean 屬性賦值時通過 doGetBean 方法從快取中獲取 lagouBean
- getSingleton 方法從三級快取中獲取 lagouBean,獲取到,存入二級快取 earlySingletonObjects,並從三級快取 singletonFactories 中刪除 lagouBean
- itBean 建立完成,addSingleton 將 itBean 加入一級快取,並從二、三級快取中刪除(此時,itBean 在三級快取,lagouBean 在二級快取)
- lagouBean 建立完成,addSingleton 將 lagouBean 加入一級快取,並從二、三級快取中刪除
第六部分 Spring AOP 應用
- AOP本質:在不改變原有業務邏輯的情況下增強橫切邏輯,橫切邏輯程式碼往往是許可權校驗程式碼、日誌程式碼、事務控制程式碼、效能監控程式碼。