XmlBeanFactory的初始化

XmlBeanFactory继承DefaultListableBeanFactory,关系图如下

XmlBeanFactory的初始化_第1张图片

内部通过XmlBeanDefinitionReader来从xml中读取bean的定义,即委托给XmlBeanDefinitionReader,XmlBeanDefinitionReader是读取xml的bean定义,委托实际的xml文档读取给BeanDefinitionDocumentReader,这个类加载一个DOM文档给BeanDefinitionDocumentReader使用,它使用给定的bean的factory注册bean的定义。在XmlBeanFactory初始化时,调用XmlBeanDefinitionReader的loadBeanDefinitions,内部将Resource对象构造成EncodedResource对象。调用loadBeanDefinitions,内部将EncodedResource对象添加到resourcesCurrentlyBeingLoaded线程对象中,通过EncodedResource对象构造成InputSource对象。调用doLoadBeanDefinitions,内部首先初始化Document对象,通过documentLoader构造Document对象,调用registerBeanDefinitions,内部通过BeanDefinitionDocumentReader对象注册bean实例。调用BeanDefinitionDocumentReader的registerBeanDefinitions,BeanDefinitionDocumentReader是BeanDefinitionDocumentReader的默认实现,这个接口根据“spring-beans”DTD and XSD格式(spring默认xml的bean定义格式)读取bean定义,xml文档需要的结构、元素、属性在这个类里硬编码,首先获取Document对象的root,读取root的profile属性,有了这个属性我们就可以在配置文件中部署两套配置来适用于生产环境和开发环境,这样可以方便地进行切换开发、部署环境,最常用的就是更换不同的数据库。parseBeanDefinitions就是进行xml的读取了。对于根节点或子节点如果是默认命名空间的话则采用parseDefaultElement方法进行解析,否则使用delegate.parseCustomElement方法对自定义命名空间进行解析。而判断是否是默认命名空间还是自定义命名空间的办法其实是使用node.getNamespaceURI()获取命名空间,并与spring中固定的命名空间进行比较。parseDefaultElement方法对import、alias、bean、beans标签进行处理。

首先我们对bean标签进行解析,首先委托BeanDefinitionParserDelegate类的parseBeanDefinitionElement方法进行元素解析,返回BeanDefinitionHolder类型的实例bdHolder,经过了这个方法后,bdHolder实例已经包含了我们配置文件中配置的各种属性了,例如class、name、id、alias之类的属性。当返回bdHolder不空的情况下若存在默认标签的子节点下再有自定义属性,还需要再对自定义标签进行解析,解析完成后,需要对解析后的bdHolder进行注册,同样,注册曹祖委托给了BeanDefinitionReaderUtils的registerBeanDefinition方法,最后发出响应事件,通知相关的监听器,这个bean已经完成加载了。

BeanDefinitionParserDelegate类的parseBeanDefinitionElement提取元素的id及name属性,进一步解析其他所有属性并统一封装至GenericBeanDefinition实例中,如果检测到bean没有指定beanName,那么使用默认规则为bean生成beanName,将获取的信息封装到BeanDefinitionHolder的实例中。parseBeanDefinitionElement方法创建用于承载属性的AbstractBeanDefinition类型的GenericBeanDefinition(Spring通过BeanDefinition将配置文件中的配置信息转换为容器的内部表示,并将这些BeanDefinition注册到BeanDefinitionRegistry中,这是第一步)然后硬编码解析默认bean的各种属性,解析元数据,解析lookup-method、replaced-method属性,解析构造函数参数,解析property子元素,解析qualifier子元素(这是第二部)

  • 解析默认bean的各种属性是通过方法parseBeanDefinitionAttributes完成的,对element所有属性进行解析,例如singleton、scope、abstract、lazy-init、autowire、depends-on等属性
  • 解析完属性后再解析子元素的meta
  • 解析子元素lookup-method,又称为获取器注入,是一种特殊的方法注入,它是把一个方法声明为返回某种类型的bean,但实际要返回的bean是在配置文件里面配置的,此方法可用在设计有些可插拨的功能上,接触程序依赖。
  • 解析子元素replaced-method,可以在运行时用新的方法替换现有的方法,与之前look-up不同,replaced-method不但可以动态替换返回实体bean,而且还能动态更改原有方法的逻辑。提取name属性(要替换的旧的方法),提取replacer属性(新的替换方法)

 

转载于:https://my.oschina.net/u/3769440/blog/3068283

你可能感兴趣的:(XmlBeanFactory的初始化)