1. 程式人生 > 實用技巧 >Spring原始碼解析之IOC容器初始化

Spring原始碼解析之IOC容器初始化

目錄

什麼是IOC

IOC(inversion of control)控制反轉,所謂控制反轉就是把我們原先程式碼中需要實現的物件建立,反轉給容器來實現,必然的我們需要建立一個容器,同樣的需要一種描述讓容器知道需要建立物件和物件之前的關係,這個描述的具體表現就是我們可配置的檔案。

DI(Dependency injection)依賴注入:就是物件是被動接受依賴類而不是自己主動去尋找,換言之就是物件不是從容器中查詢它的依賴類而是在容器例項化的時候主動把它的依賴類注入給它。

我們從巨集觀的設計視角來俯瞰整個架構考慮,如果我們是ioc的設計者,我們該怎麼解決如下問題:
物件和物件之間的關係怎麼描述?
可以採取xml,properties檔案或者註解的方式表示。

描述物件關係的檔案放在哪裡?
可能是classPath,filesystem,或者是url網路資源,servletContext等等。

有了配置檔案之後,我們還需要對配置檔案進行解析,
不同的配置檔案對物件的描述不一樣,如標準的,如自定義宣告的,如何統一?在內部需要有一個統一的關於物件的定義,所以外部描述必須轉化成統一的描述定義。

如何對不同的配置檔案進行解析?
需要對不同的配置檔案語法,採取不同的解析器。

Spring IOC體系架構

帶著上述的問題我們正式進入Spring IOC原始碼之旅。
首先我們先丟擲一些概念及定義

BeanFactory

Spring Bean 的建立是典型的工廠模式,這一系列的Bean 工廠,也即IOC 容器為開發者管理物件間的依賴關係提供了很多便利和基礎服務,在Spring 中有許多的IOC 容器的實現供使用者選擇和使用,其相互關係如下:
在這裡插入圖片描述
其中BeanFactory 作為最頂層的一個介面類,它定義了IOC 容器的基本功能規範,BeanFactory 有三個重要的子類:ListableBeanFactory、HierarchicalBeanFactory 和AutowireCapableBeanFactory。但是從類圖中我們可以發現最終的預設實現類是DefaultListableBeanFactory,它實現了所有的介面。那為何要定義這麼多層次的介面呢?查閱這些介面的原始碼和說明發現,每個介面都有它使用的場合,它主要是為了區分在Spring 內部在操作過程中物件的傳遞和轉化過程時,對物件的資料訪問所做的限制。例如ListableBeanFactory 介面表示這些Bean 是可列表化的,而HierarchicalBeanFactory 表示的是這些Bean 是有繼承關係的,也就是每個Bean 有可能有父Bean。AutowireCapableBeanFactory 介面定義Bean 的自動裝配規則。這三個介面共同定義了Bean 的集合、Bean 之間的關係、以及Bean 行為

在BeanFactory 裡只對IOC 容器的基本行為作了定義,根本不關心你的Bean 是如何定義怎樣載入的。正如我們只關心工廠裡得到什麼的產品物件,至於工廠是怎麼生產這些物件的,這個基本的介面不關心。而要知道工廠是如何產生物件的,我們需要看具體的IOC 容器實現,Spring 提供了許多IOC 容器的實現。比如GenericApplicationContext , ClasspathXmlApplicationContext 等。ApplicationContext 是Spring 提供的一個高階的IOC 容器,它除了能夠提供IOC 容器的基本功能外,還為使用者提供了以下的附加服務。從ApplicationContext 介面的實現,我們看出其特點:

1、支援資訊源,可以實現國際化。(實現MessageSource 介面)
2、訪問資源。(實現ResourcePatternResolver 介面,後面章節會講到)
3、支援應用事件。(實現ApplicationEventPublisher 介面)

BeanDefinition

SpringIOC 容器管理了我們定義的各種Bean 物件及其相互的關係,Bean 物件在Spring 實現中是以BeanDefinition 來描述的,其繼承體系如下:
在這裡插入圖片描述

BeanDefinitionReader

Bean 的解析過程非常複雜,功能被分的很細,因為這裡需要被擴充套件的地方很多,必須保證有足夠的靈活性,以應對可能的變化。Bean 的解析主要就是對Spring 配置檔案的解析。這個解析過程主要通過BeanDefintionReader 來完成,最後看看Spring 中BeanDefintionReader 的類結構圖:
在這裡插入圖片描述
在XmlBeanDefinitionReader中主要包含以下幾步的處理:

(1):通過繼承AbstractBeanDefinitionReader中的方法,來使用ResourceLoader將資原始檔路勁轉換為對應的Resource檔案。

(2):通過DocumentLoader對Resource檔案進行轉換,將Resource檔案轉換為Document檔案。

(3):通過實現介面BeanDefinitionDocumentReader的DefaultBeanDefinitionDocumentReader類對 Document 進行解析,並使用BeanDefinitionParserDelegate對Element進行解析。

IOC容器的初始化