Spring源碼分析之配置文件加載並註冊Bean

Bean的容器加載: (六種加載xml文件的方式:1.XmlBeanFactory 引用資源  2.ClassPathXmlApplicationContext  編譯路徑 3.用文件系統的路徑

4.XmlWebApplicationContext是專爲Web工程定製的 5. 使用BeanFactory  6. Web 應用啓動時加載多個配置文件 

Spring 通過BeanDefinition將配置文件中的<bean>配置信息轉換爲容器的內部表示,並將這些BeanDefinition註冊到BeanDefinitionRegistry中


在XmlBeanFactory中創建一個XmlBeanDefinitionReader 實例來進行資源文件讀取、解析及註冊等操作。

   (資源加載的切入點)



資源解析流程:

1. loadBeanDefinitions(Resource resource)  對資源文件編碼進行處理

loadBeanDefinitions(new EncodedResource(resource));

2. loadBeanDefinitions(EncodedResource encodedResource) 將資源文件轉換成inputStream
3. doLoadBeanDefinitions(inputSource, encodedResource.getResource()) 將inputStream轉換成document
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
      throws BeanDefinitionStoreException {
   try {
      Document doc = doLoadDocument(inputSource, resource);
      return registerBeanDefinitions(doc, resource);
   }
4. registerBeanDefinitions(Document doc, Resource resource) 提取及註冊Bean
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
   //實例化DefaultBeanDefinitionDocumentReader(單一職責原則)
   BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
   //記錄統計當前 BeanDefinition的加載個數
   int countBefore = getRegistry().getBeanDefinitionCount();
   //加載及註冊 Bean
   documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
   //記錄本次加載的 BeanDefinition個數
   return getRegistry().getBeanDefinitionCount() - countBefore;

5. registerBeanDefinitions(Document doc, XmlReaderContext readerContext) 根據解析文檔提取參數繼續註冊BeanDefinition
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
   this.readerContext = readerContext;
   logger.debug("Loading bean definitions");
   Element root = doc.getDocumentElement();
   //XML文檔解析完成,根據解析參數註冊
   doRegisterBeanDefinitions(root);
}

6. doRegisterBeanDefinitions(Element root) 開始解析文本標籤信息

Profile將Bean的定義進行更細粒度的劃分,將這些定義的Bean劃分爲幾個不同的組,當Spring容器加載配置信息的時候,首先查找激活的Profile,然後只會去加載被激活的組中所定義的Bean信息,而不被激活的Profile中所定義的Bean定義信息是不會加載用於創建Bean.

7. parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) 解析標籤

8. parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate)  默認的標籤解析中,對各個標籤的處理

9.processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) 對Bean標籤進行解析及註冊

10.parseBeanDefinitionElement(Element ele, BeanDefinition containingBean)
1.提取元素中的id 以及 name 屬性
2.進一步解析其他所有屬性並統一封裝至 GenericBeanDefinition 類型的實例中
3.如果Bean無指定beanName,則按規則生成beanName
4.將屬性信息封裝到 BeanDefinitionHolder的實例中




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