僅需16 張圖帶你解鎖 Spring 的整體脈絡

今天來梳理下

Spring

的整體脈絡啦,為後面的文章做個鋪墊~

話說咱們一直都在用這個 Spring ,你們對它的感受是啥呀?還是說說不出來 哈哈

4ye 的感覺也是零零散散的,而且印象中一直都在用 Springboot ,不用再配置一堆東西呀,管理依賴啥的,方便太多了。

所以藉此機會簡單梳理下其中的一些脈絡,這樣去看原始碼就有條理多啦,更能知道一些擴充套件點的使用等:stuck_out_tongue_closed_eyes:

目錄

本文會先大概介紹下這些知識點 :point_down:

僅需16 張圖帶你解鎖 Spring 的整體脈絡

印象中的 Spring

腦海中有這麼一條公式:

:point_right: IOC = 工廠模式 + XML + 反射

:point_right: 而 DI , AOP ,

事務

等也都在 XML 中很直觀的表現出來

雖然我們現在大部分用這個註解來代替,但是原理還是基本一樣的:pig2:

註解使用起來很方便,但是學習的話,還是建議先透過這個 XML ,畢竟結構性的文件,有層次感,可以留下更深的印象~ :smile:

小小Spring

把 Spring 濃縮一下,就有了這麼一點小東西:pig2:

僅需16 張圖帶你解鎖 Spring 的整體脈絡

想了下,我們用 Spring ,其中最主要的一點,就是用它來幫我們管理,建立這個 Bean 。

那麼先從源頭看起 —— Bean 從哪來 (@_@;)

Bean 解析流程

僅需16 張圖帶你解鎖 Spring 的整體脈絡

如圖所示,就是透過

解析器

,對我們的 XML 檔案或者註解進行解析,最後將這些資訊封裝在 BeanDefinition 類中,並透過 BeanDefinitionRegistry 介面將這些資訊

註冊

起來,放在 beanDefinitionMap 變數中, key : beanName , value :BeanDefinition

簡單看看 BeanDefinition 中的屬性叭

BeanDefinition

beanClass : bean 的型別 ,例項化時用的 :pig2:

scope : 作用範圍有 singleton,prototype

isLazy :

懶載入

,true 的話 會在 getBean 時生成,而且 scope 的 prototype 無效,false 在 Spring 啟動過程中直接生成

initMethodName : 初始化方法,當然是初始化時呼叫:pig2:

primary : 主要的,有多個 Bean 時使用它

dependsOn : 依賴的Bean,必須等依賴Bean 建立好才可以建立

PS: @Component ,@Bean , 都會被解析成 BeanDefinition

反射

有了原料後呢, 咱 們再來看看這個

工廠

BeanFactory

先簡單想一想這個工廠要怎麼建立這個 Bean 呢?

沒錯,肯定就是這個

反射

啦 :smile:

那麼,結合我們從原料中獲取的重要屬性之一的 beanClass ,我們可以畫出這麼一張圖 :point_down:

僅需16 張圖帶你解鎖 Spring 的整體脈絡

那麼我們再來看看這個 BeanFactory 叭 :smile:

BeanFactory

先來看看 作為IOC 容器的

根介面

的 BeanFactory 提供了什麼方法吧:point_down:

僅需16 張圖帶你解鎖 Spring 的整體脈絡

主要是這個 getBean 方法,以及

別名獲取

型別獲取

方法和其他一些判斷方法如 :

單例

多例

型別匹配

包含bean

我們來簡單看看它的子介面都有哪些叭~:smile:

這裡分享個小技巧叭:pig2:

看原始碼的時候,一般就直接看這個

預設

介面 如這裡的 DefaultListableBeanFactory

僅需16 張圖帶你解鎖 Spring 的整體脈絡

基本上看個類名就知道大概作用了,那麼先對號入座下:point_down:

ListableBeanFactory

:point_right: 遍歷 bean

HierarchicalBeanFactory

:point_right: 提供 父子關係,可以獲取上一級的 BeanFactory

ConfigurableBeanFactory

:point_right: 實現了 SingletonBeanRegistry ,主要是 單例Bean的註冊,生成

AutowireCapableBeanFactory

:point_right: 和自動裝配有關的

AbstractBeanFactory

:point_right: 單例快取,以及 FactoryBean 相關的

ConfigurableListableBeanFactory

:point_right: 預例項化單例Bean,分析,修改 BeanDefinition

AbstractAutowireCapableBeanFactory

:point_right: 建立 Bean ,屬性注入,例項化,呼叫初始化方法 等等

DefaultListableBeanFactory

:point_right: 支援單例Bean ,Bean別名 ,父子BeanFactory,Bean 型別轉化 ,Bean 後置處理,FactoryBean,自動裝配等

是不是非常豐富 :smile:

FactoryBean

FactoryBean ,它本身就是個 Bean,算是小工廠 ,歸 BeanFactory 這個大工廠管理的。

僅需16 張圖帶你解鎖 Spring 的整體脈絡

可以看到它就只有三個方法

getObject() 獲取物件

isSingleton() 單例物件

getObjectType() 返回的是 Bean 物件的型別

相比大工廠 BeanFactory 少了特別多東西,沒有嚴格的 Bean 生命週期流程

在 :point_right: 《三分鐘快速瞭解Spring中的工廠模式》 一文中有介紹到 :smile:

FacotryBean 物件本身也是一個Bean,是一個小工廠,可以生產另外的 Bean

BeanFactory 是 Spring 容器的根介面,是大工廠,生產各種各樣的Bean

beanName 就是正常物件

“&”+beanName , 獲取的是實現了該介面的 FacotryBean 工廠物件

大致如下 :point_down:

僅需16 張圖帶你解鎖 Spring 的整體脈絡

ApplicationContext

我們再來看看這個 ApplicationContext

僅需16 張圖帶你解鎖 Spring 的整體脈絡

可以看到它擴充套件了很多功能,除了 BeanFactory ,它還可以

建立 , 獲取 Bean

,以及處理

國際化

事件

獲取資源

EnvironmentCapable 獲取 環境變數 的功能,可以獲取到

作業系統變數

JVM 環境變數

ListableBeanFactory 獲取所有 BeanNames,判斷某個 BeanName 是否存在 BeanDefinition 物件,統計 BeanDefinition 物件,獲取某個型別對應的所有 beanNames 等功能

HierarchicalBeanFactory 獲取父 BeanFactory ,判斷某個 name 是否存在 bean 物件的功能

MessageSource

國際化功能

,獲取某個國際化資源

ApplicationEventPublisher

事件釋出功能

(重點)

ResourcePatternResolver

載入,獲取資源的功能

,這裡的資源可能是檔案,圖片 等某個URL資源都可以

還有這三個重要的類:point_down:,就不一一介紹先啦:smile:

ClassPathXmlApplicationContext

AnnotationConfigApplicationContext

FileSystemXmlApplicationContext

趕緊來看看這個核心叭!

IOC 容器

當然,這時候出場的肯定是 IOC 啦。

我們都知道 IOC 是

控制反轉

,但是別忘了

容器

這個詞,比如 **容器的根介面 **BeanFactory ,

容器的實現

:point_down:

ClassPathXmlApplicationContext

AnnotationConfigApplicationContext

FileSystemXmlApplicationContext

同時我們要注意這裡無處不在的

後置處理器

xxxPostProcessor :pig:

這個是 Spring 中擴充套件性強的原因了!

我們可以在各個過程中合理應用這些 PostProcessor 來擴充套件,或者修改 Bean 定義資訊等等

僅需16 張圖帶你解鎖 Spring 的整體脈絡

可以看到在這個容器中,完成了 Bean 的初始化,而這個過程還有很多細節 ,請往下看看:point_down:

DI 到時寫

屬性填充

時再介紹:pig:

BeanFactory 後置處理器

作為 IOC 容器根介面的 BeanFactory ,有著非常高的擴充套件性,比如最開始獲取原料 BeanDefinition 時,就出現了兩個針對 BeanFactory 工廠的後置處理器 :point_down:

BeanDefinitionRegistryPostProcessor

透過該介面,我們可以自己掌控我們的

原料

,透過 BeanDefinitionRegistry 介面去

新增

刪除

獲取

我們這個 BeanDefinition

BeanFactoryPostProcessor

透過該介面,可以在

例項化物件前

,對 BeanDefinition 進行修改 ,

凍結

預例項化單例Bean

經過上面層層阻礙後,我們最終會來到目標方法 getBean ,將原料投入生產,最終獲取一個個 Bean 物件出來

那麼隨之而來的就是這個 Bean 的生命週期啦 :smile:

Bean 生命週期

Bean 的建立和管理有

標準化的流程

這裡在我們的工廠 BeanFactory 中寫得很清楚 :point_down:

僅需16 張圖帶你解鎖 Spring 的整體脈絡

總共

14

個步驟,是不是一下子就清晰多了:smile:

僅需16 張圖帶你解鎖 Spring 的整體脈絡

在看這部分的原始碼時,要多注意兩個英文單詞 :stuck_out_tongue_closed_eyes:

例項化:point_right:

Instantiation

初始化:point_right:

Initialization

ps: 別看快搞錯了 哈哈:stuck_out_tongue_closed_eyes:

仔細閱讀上面這14個步驟,會發現前面

8

個都是 Aware 介面,而他們的作用也很簡單,就是獲取 xxAware 這個單詞的字首 xx :smile:

比如我們在上文 :point_right: 《三分鐘快速上手Spring事件機制》 中提到的事件釋出器 ApplicationEventPublisher ,只要你實現了 ApplicationEventPublisherAware 介面,就可以

獲取

事件釋出器 ApplicationEventPublisher !

Bean 後置處理器

在例項化 和 初始化流程中,把這個Bean 的後置處理器 BeanPostProcessor 安排上,就得到下圖啦 :point_down:

僅需16 張圖帶你解鎖 Spring 的整體脈絡

這裡留意下

例項化

有擴充套件點 InstantiationAwareBeanPostProcessor ,

初始化

擴充套件點 BeanPostProcessor 就非常多啦,我們主要來關注下這個 AOP

AOP

那麼 AOP 是在哪個步驟代理物件的呢?:point_down:

僅需16 張圖帶你解鎖 Spring 的整體脈絡

可以在 AbstractAutoProxyCreator 類中看到 :point_down:

僅需16 張圖帶你解鎖 Spring 的整體脈絡

總結

本文就先介紹到這裡啦:pig2:

主要介紹了 Spring 裡面的這些脈絡,方便小夥伴們對它有個整體的印象先~

再介紹其中的一些擴充套件點,比如從源材料的 BeanFactoryPostprocessor ,到產物 Bean 的 BeanPostprocessor 。

例項化,初始化的順序,Bean的生命週期,以及 BeanFactory 及子類擴充套件的功能,再到 ApplicationContext 的功能。

還有這個核心機制:

工廠+XML+反射

,以及引出下文要說的 AOP

發生的地方

僅需16 張圖帶你解鎖 Spring 的整體脈絡

原文連結:https://www。tuicool。com/articles/m6NRzeZ