1-Spring IoC容器設計原理(Spring Boot2)

IoC即Inversion of Control控制反轉,反轉的是依賴對象的創建工作,一般情況下,面向對象編程中,對象和對象之間絕大多數情況下需要複雜的依賴才能完成工作,而引用對象的創建工作也由引用者自行創建,這種方式使得對象之間的耦合程度大大增加,同時也無法以一種簡單方式複用一些單例對象。這個時候IoC方案就誕生了,IoC方案旨在將依賴對象的創建工作從對象本身剝離,交給框架解決,使對象之間的依賴關係變得更加純粹,不用考慮實例化依賴等各種問題。

在查看Spring關於IoC容器相關的源碼瞭解其中設計原理時,我們千萬不能掉進具體實現的細節裏,要站在一個系統設計高度來看,不然很難窺測到Spring IoC容器設計的原理。首先我們看到BeanFactory是IoC容器設計裏的頂級接口,如果將他的實現全部展開來看,有涉及數百個接口和實現類,是個龐大的工程,根本沒辦法看完。所以我們一定要抓住主流程。

儘管有衆多IoC容器的實現類,但是我們要知道,可以分爲兩類,一類是基本功能的IoC容器實現,後綴爲BeanFactory,另一類爲應用擴展IoC容器實現,後綴爲ApplicationContext,同時XXXBeanFactory一定是YYYApplicationContext的父類或接口,且YYYApplicationContext的數量遠大於XXXBeanFactory數量,先從整體框架上定量定性分析這些類型關係。然後我們逐個擊破這兩類Ioc容器。

先從BeanFactory下手,由於這XXXBeanFactory系列涉及的類比較少,給個完整的類圖出來,需要指出的是XmlBeanFactory已經在Spring 3.1以後廢棄,這個類並沒有具體邏輯處理,廢棄後對用戶影響不大,他的功能可以使用ClassPathXmlApplicationContext這個類來替代。但是XmlBeanFactory卻是多個BeanFactory的葉子節點類。

下面這個圖看起來類很多,但是有很多重複,簡化後應該和上面一樣

結合這兩個類圖可以看出,BeanFactory規定了一些功能,基本接口是以下4個,其他的接口或類型都是這幾個功能的組合,需要注意的是,設計上拆開只是爲了合理的設計,但是在最終的實現類,肯定是這些功能的綜合體,比如HierarchicalBeanFactory決定了IoC容器是有父子關係的,並不是說有哪個具體的IoC容器實現類只會具有Hierarchical這一個功能屬性,之所以設計這個接口是爲了分清楚實現職責,最終的用戶可用實現類型往往是具備全部功能的類。
ListableBeanFactory接口:
HierarchicalBeanFactory接口:
AutowireCapableBeanFactory接口:
ConfigurableBeanFactory接口(繼承自HierarchicalBeanFactory):
這裏需要我們注意的幾個具體實現類型有
AbstractBeanFactory(1796行|實現了ConfigurableBeanFactory接口),是個實現複雜的抽象類,
AbstractAutowireCapableBeanFactory(1955行|繼承了AbstractBeanFactory並實現了AutowireCapableBeanFactory接口),
DefaultListableBeanFactory(2006行|繼承了AbstractAutowireCapableBeanFactory並實現了ConfigurableListableBeanFactory接口),這幾個類依次功能累加,所以功能最多的就是DefaultListableBeanFactory,他是集大成者,這三個類的代碼量也相差無幾,都在2000行上下,在沒有搞清楚這些類的關係時,我曾一度陷入Spring到底實例化了多少IoC容器實現類的迷茫中無法自拔,後來在實現細節和宏觀結構之間反覆掙扎才讓自己明白。

接下來我們就要看看YYYApplicationContext系列的類型是如何設計的了,ApplicationContext接口是整個YYYApplicationContext系列的頂級接口。由於ApplicationContext是針對應用而言的,所以實現類是多種情況,不會像BeanFactory那樣有功能上集大成的類型出現,ApplicationContext就是將多種情況拆開實現的,並且在程序啓動時往往只會實例化應用對應的ApplicationContext,這一點是需要先整體認知的,不然無法從整體上理解運行流程。另外,Spring在設計上主要是給web應用使用,但是也可以用在非web應用上,所以在ApplicationContext設計上應該是保留了這個設計和使用的。ApplicationContext的直接子接口有兩個ConfigurableApplicationContextWebApplicationContext,注意這兩個接口分屬context包和web包下,說明了他們的“階級”區別。先來看看ApplicationContext的繼承體系:

ApplicationContext接口只繼承了ListableBeanFactory和HierarchicalBeanFactory兩個BeanFactory系列的接口, 然後ConfigurableApplicationContext繼承了ApplicationContext,體現了接口功能拆分的設計,我們可以聯想下BeanFactory系列中也有個ConfigurableBeanFactory接口,這種設計還是有一定對稱性的。ApplicationContext的其他子接口可以忽略,使用的情況並不是很多。
接下來我們要介紹一個及其重要的類型:AbstractApplicationContext,這個抽象類型是所有ApplicationContext幾乎都間接繼承的一個類型,

我用紅色框出來的就是常用的ApplicationContext葉子節點類型,其中AnnotationConfigServletWebServerApplicationContext是在springboot環境下的實例化類型。其中的重點是GenericApplicationContext和AbstractRefreshableApplicationContext兩個作爲AbstractApplicationContext的子類,都持有一個beanFactory

private DefaultListableBeanFactory beanFactory;

看清楚了沒有,這是BeanFactory和ApplicationContext之間的一個最重要的關係,聚合關係

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章