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




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