(spring-第8回【IoC基礎篇】)BeanDefinition在IoC容器中的注冊


在spring中,所有的bean都是由BeanFactory進行管理的。下面是BeanFactory的類體系結構:

我們清楚的看到,DefaultListableBeanFactory繼承了BeanFactory的優良傳統,同時又實現了BeanDefinitionRegistry這個注冊器,那么無疑,BeanDefinition在容器中的注冊任務,非他莫屬。事實上,DefaultListableBeanFactory擁有一個私有的BeanDefinitonMap屬性,這個屬性是個哈希Map,通過把解析好的BeanDefiniton放到哈希Map中,就完成了注冊。下面是注冊方法:

 1 //---------------------------------------------------------------------
 2     // Implementation of BeanDefinitionRegistry interface
 3     //---------------------------------------------------------------------
 4 
 5     public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
 6             throws BeanDefinitionStoreException {
 7 
 8        。。。。。。40         
41             this.beanDefinitionMap.put(beanName, beanDefinition); 42             
43 
44             resetBeanDefinition(beanName);
45         }
46     }

第41行把beanDefinition作為value,而把beanName作為key,放到beanDefinitionMap中,就完成了注冊。那么,這個beanDefinition是從哪里傳過來的呢?

由於我的myeclipse環境中使用的是spring源碼,而非jar包,所以我們做一個小測試,我配置一個簡單的<bean>,然后做一個惡簡單的spring容器的啟動和<bean>的加載,那么程序一定會走到41行來執行注冊。我在第41行上面加上一句:beanDefinition=null;這樣的話,執行到第41行就會報錯,報錯信息如下:

。。。。。。
17 Caused by: java.lang.NullPointerException 18 at java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:881) 19 at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:628) 20 at org.springframework.beans.factory.support.BeanDefinitionReaderUtils.registerBeanDefinition(BeanDefinitionReaderUtils.java:148) 21 at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.processBeanDefinition(DefaultBeanDefinitionDocumentReader.java:263) 22 at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseDefaultElement(DefaultBeanDefinitionDocumentReader.java:153) 23 at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:132) 24 at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:93) 25     at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493) 26     at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390) 27     ... 14 more

從第26行倒着往上看,就是整個beanDefinition的加載與注冊過程。大概過程我們一目了然:

1.由XmlBeanDefinitionReader開始加載、注冊。

2.由DefaultBeanDefinitionDocumentReader開始解析。

3.由BeanDefinitionReaderUtils過渡。

4.由DefaultListableBeanFactory注冊。

我們來具體分析一下這四個類。

解讀第1步:Resource在加載了XML文件后,首先是由BeanDefinitionReader來解析的。下面是BeanDefinitionReader的部分子孫圖和注釋:

 

解讀第2步:那么第二步所說的DefaultBeanDefinitionDocumentReader應該就是圖中提到的"BeanDefinitionDocumentReader"的某個子孫了。它負責與BeanDefinitionRegistry的實現者對話。而這個"BeanDefinitionRegistry的實現者"就是DefaultListableBeanFactory。

BeanDefinitionDocumentReader的家族圖也很簡單,它的家譜圖說明:

解讀第3步:過渡類。

解讀第4步:文章一開始已經分析過了。實際上,DefaultListableBeanFactory能做的事情很多,除了注冊BeanDefinition外,它可以被用作一個獨立的BeanFactory,又可以被基本的BeanFactory子類來繼承,打開API文檔你會看到,DefaultListableBeanFactory繼承和實現了一堆父類,親爹干爹一大堆,API上描述其為:"a full-fledged bean factory"(羽翼豐滿的bean factory),下面是它的親爹和干爹們:

沒錯,在spring王國里,它就是富二代。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM