天天看點

死磕Spring系列之四 BeanDefinition接口、BeanFactory接口

通過前面的介紹,相信大家對bean的解析,注冊的整體流程了解了,知道spring怎麼一步步将xml文檔内的配置資訊納入容器中。有幾個非常重要的接口,不得不談。

1.beandefinition接口

這個接口,可以了解為xml bean元素的資料載體。通過對比xml bean标簽的屬性清單和beandefinition的屬性清單一看便知。

我的了解,是解析xml的過程,就是 xml <bean>元素内容 轉換為beandefinition對象的過程。而且這個接口,支援層級,對應對象的繼承。

有一個類beandefinitionholder,beandefinitionholder,根據名稱或者别名持有beandefinition,它承載了name和beandefinition的映射資訊。

beanwarpper:

提供對标準javabean的分析和操作方法:單個或者批量擷取和設定屬性值,擷取屬性描述符,查詢屬性的可讀性和可寫性等。支援屬性的嵌套設定,深度沒有限制。

死磕Spring系列之四 BeanDefinition接口、BeanFactory接口

<a href="http://s2.51cto.com/wyfs02/m02/78/7c/wkiol1z98ttw-bfgaacsvhtqwgm923.png" target="_blank"></a>

attributeaccessor:接口定義了最基本的對任意對象的中繼資料的修改或者擷取

beanmetadataelement:用來傳輸一個可配置的源對象(源碼)

childbeandefinition是一種bean definition,它可以繼承它父類的設定,即childbeandefinition對rootbeandefinition有一定的依賴關系(現在spring源碼中已不使用了)。childbeandefinition從父類繼承構造參數值,屬性值并可以重寫父類的方法,同時也可以增加新的屬性或者方法。(類同于java類的繼承關系)。注意:從spring 2.5 開始,提供了一個更好的注冊bean definition類genericbeandefinition,它支援動态定義父依賴,方法是 genericbeandefinition.setparentname(java.lang.string),genericbeandefinition 可以有效的替代childbeandefinition的絕大分部使用場合。我發現在spring3.1.2版本中,該類已經不被使用了。

genericbeandefinition是一站式的标準bean definition,除了具有指定類、可選的構造參數值和屬性參數這些其它bean definition一樣的特性外,它還具有通過parenetname屬性來靈活設定parent bean definition。

通常, genericbeandefinition用來注冊使用者可見的bean definition(可見的bean definition意味着可以在該類bean definition上定義post-processor來對bean進行操作,甚至為配置parent name做擴充準備)。<code>rootbeandefinition</code> / <code>childbeandefinition用來預定義具有</code>parent/child關系的bean definition。

  一個rootbeandefinition定義表明它是一個可合并的bean definition:即在spring beanfactory運作期間,可以傳回一個特定的bean。rootbeandefinition可以作為一個重要的通用的bean definition 視圖。

rootbeandefinition用來在配置階段進行注冊bean definition。然後,從spring 2.5後,編寫注冊bean definition有了更好的的方法:genericbeandefinition。genericbeandefinition支援動态定義父類依 賴,而非寫死作為root bean definition。其中rootbeandefinition是最常用的實作類,它對應一般性的&lt;bean&gt;元素标簽

在 配置檔案中可以定義父&lt;bean&gt;和子&lt;bean&gt;,父&lt;bean&gt;用rootbeandefinition表示, 而子&lt;bean&gt;用childbeandefiniton表示,而沒有父&lt;bean&gt;的&lt;bean&gt;就使用 rootbeandefinition表示。

2.beanfactory接口

死磕Spring系列之四 BeanDefinition接口、BeanFactory接口
死磕Spring系列之四 BeanDefinition接口、BeanFactory接口

主要是這幾個類或接口

configurablebeanfactory:提供配置factory的各種方法。一般應用用不到,主要為listablebeanfactory和beanfactory支援

listablebeanfactory:根據條件擷取bean的配置清單

configurablelistablebeanfactory:擷取 beandefinition 和預先執行個體化單例 bean 的功能。beanfactory配置清單,指定忽略類型及接口

autowirecapablebeanfactory:提供自動裝配的功能,提供建立,注入,初始化及應用bean的後處理器

hierarchicalbeanfactory:層級管理

如果,硬性了解這幾個類分别有什麼含義,有點苦澀。可以逆向思考一下。把這些工廠想象成一個裁縫,會友善了解些。

configurablebeanfactory:你對要求衣服的樣式要求

listablebeanfactory:需求材料清單

autowirecapablebeanfactory:縫紉機,針線工具

hierarchicalbeanfactory: 套裝使用

configurablelistablebeanfactory:裁縫的助手

3.applicationcontext接口

可以說是我們業務系統,主要面對的接口。spring強大的擴充功能,全在這裡實作。通過内部調用beanfactory初始化,對使用者透明。

死磕Spring系列之四 BeanDefinition接口、BeanFactory接口

abstractrefreshableconfigapplicationcontext:指定配置路徑

abstractrefreshableapplicationcontext: 支援多次調用refresh.實作了refreshbeanfactory方法,供abstractapplicationcontext調用。

abstractapplicationcontext:模闆模式實作初始化過程

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

<code>  </code><code>publicvoid refresh() </code><code>throws</code> <code>beansexception, illegalstateexception {</code>

<code>      </code><code>synchronized</code> <code>(</code><code>this</code><code>.startupshutdownmonitor) {</code>

<code>         </code><code>// prepare this context for refreshing.</code>

<code>         </code><code>preparerefresh();</code>

<code> </code> 

<code>         </code><code>// tell the subclass to refresh the internal bean factory.</code>

<code>         </code><code>configurablelistablebeanfactory beanfactory = obtainfreshbeanfactory();</code>

<code>         </code><code>// prepare the bean factory for use in this context.</code>

<code>         </code><code>preparebeanfactory(beanfactory);</code>

<code>         </code><code>try</code> <code>{</code>

<code>            </code><code>// allows post-processing of the bean factory in context subclasses.</code>

<code>            </code><code>postprocessbeanfactory(beanfactory);</code>

<code>            </code><code>// invoke factory processors registered as beans in the context.</code>

<code>            </code><code>invokebeanfactorypostprocessors(beanfactory);</code>

<code>            </code><code>// register bean processors that intercept bean creation.</code>

<code>            </code><code>registerbeanpostprocessors(beanfactory);</code>

<code>            </code><code>// initialize message source for this context.</code>

<code>            </code><code>initmessagesource();</code>

<code>            </code><code>// initialize event multicaster for this context.</code>

<code>            </code><code>initapplicationeventmulticaster();</code>

<code>            </code><code>// initialize other special beans in specific context subclasses.</code>

<code>            </code><code>onrefresh();</code>

<code>            </code><code>// check for listener beans and register them.</code>

<code>            </code><code>registerlisteners();</code>

<code>            </code><code>// instantiate all remaining (non-lazy-init) singletons.</code>

<code>            </code><code>finishbeanfactoryinitialization(beanfactory);</code>

<code>            </code><code>// last step: publish corresponding event.</code>

<code>            </code><code>finishrefresh();</code>

<code>         </code><code>}</code>

<code>         </code><code>catch</code> <code>(beansexception ex) {</code>

<code>            </code><code>logger.warn(</code><code>"exception encountered during context initialization - cancelling refresh attempt"</code><code>, ex);</code>

<code>            </code><code>// destroy already created singletons to avoid dangling resources.</code>

<code>            </code><code>destroybeans();</code>

<code>            </code><code>// reset 'active' flag.</code>

<code>            </code><code>cancelrefresh(ex);</code>

<code>            </code><code>// propagate exception to caller.</code>

<code>            </code><code>throw</code> <code>ex;</code>

<code>      </code><code>}</code>

<code>   </code><code>}</code>

下面是針對該過程的各步驟分析(來自spring 深度源代碼分析)