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的實例中