天天看點

spring bean 的加載機制(源碼分析)

       xml的讀取應該是spring的重要功能,因為spring的大部分功能都是以配置做為切入點的。

       我們在靜态代碼塊中讀取配置檔案可以這樣做:

       (1)xmlbeanfactory 繼承 abstractbeandefinitionreader ,使用resourceloader 将資源檔案路徑轉換為對應的resource檔案。

       (2)通過documentloader 對 resource 檔案進行轉換,将 resource 檔案轉換為 document 檔案。

       (3)通過實作接口 beandefinitiondocumentreader 的 defaultbeandefinitiondocumentreader 類對document 進行解析,并且使用 beandefinitionparserdelegate對element進行解析。

step1:

spring bean 的加載機制(源碼分析)

     在平常開發中,我們也可以使用resource 擷取 資源檔案:

step2:

spring bean 的加載機制(源碼分析)

      在資源實作加載之前,調用了 super(parentbeanfactory) --  /**ignore the given dependency interface for autowiring.(忽略接口的自動裝配功能)*/

      調用xmlbeandefinitionreader 的 loadbeandefinitions()方法進行加載資源:

      (1) 對resource資源進行編碼

      (2) 通過sax讀取xml檔案來建立inputsource對象

      (3) 核心處理

spring bean 的加載機制(源碼分析)

       可以很直覺的看出來是這個function是在解析xml檔案進而獲得對應的document對象。

spring bean 的加載機制(源碼分析)

      在doloaddocument方法裡面還存一個方法getvalidationmodeforresource()用來讀取xml的驗證模式。(和我關心的沒什麼關系,暫時不看了~)

      轉換成document也是最常用的方法:

spring bean 的加載機制(源碼分析)

step3 : 我們已經step by step 的看到了如何将xml檔案轉換成document的,現在就要分析是如何提取和注冊bean的。

            /**register the bean definitions contained in the given dom document*/

spring bean 的加載機制(源碼分析)

參數doc是doloadbeandefinitions()方法傳進來的  loaddocument 加載過來的。這邊就很好的展現出了面向對象的單一全責原則,将邏輯處理委托給單一的類去處理。

在這邊單一邏輯處理類是:  beandefinitiondocumentreader

核心方法:  documentreader.registerbeandefinitions(doc, createreadercontext(resource));

spring bean 的加載機制(源碼分析)

開始解析:

spring bean 的加載機制(源碼分析)

-------------

在spring的xml配置中有兩種方式來聲明bean:

     一種是預設的:  <bean id = " " class = " " />

     還有一種是自定義的:  < tx : annotation-driven / >

spring bean 的加載機制(源碼分析)

通過xml配置檔案的預設配置空間來判斷:http://www.springframework.org/schema/beans

對于預設标簽的解析:

spring bean 的加載機制(源碼分析)

對bean 配置的解析:

spring bean 的加載機制(源碼分析)

<b>beandefinitionholder bdholder = delegate.parsebeandefinitionelement(ele);  傳回beandefinitionholder</b>

<b></b>

spring bean 的加載機制(源碼分析)
spring bean 的加載機制(源碼分析)

這邊代碼大緻看下來:

  提取元素中的id和name屬性

  進一步解析将其他屬性封裝到 beandefinition 的實作類中

  如果沒有指定beanname 變使用預設規則生成beanname

封裝類beandefinitionholder

可以先了解一下  beandefinition  這個類的作用。

      beandefinition是一個接口,對應着配置檔案中&lt;bean&gt;裡面的所有配置,在spring中存在着三個實作類:

spring bean 的加載機制(源碼分析)

      在配置檔案中,可以定義父&lt;bean&gt;和子&lt;bean&gt;,父&lt;bean&gt;是用rootdefinition來表示,子&lt;bean&gt;是用childbeandefinition來表示。

      spring 通過beandefiniton将配置檔案中的&lt;bean&gt;配置資訊轉換為容器内部表示,并且将這些beandefinition注冊到beandefinitonregistry中。

spring容器的beandefinitonregistry就像是spring配置資訊的記憶體資料庫,主要是以map的形式儲存的。

     是以解析屬性首先要建立用于承載屬性的執行個體:

spring bean 的加載機制(源碼分析)

然後就是各種對屬性的解析的具體方法:

spring bean 的加載機制(源碼分析)