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