定义一个Bean
在xml配置文件之中配置好
使用BeanFactory获取Bean
使用到了XmlBeanFactory,看XmlBeanFactory的类结构图
最上层是3个接口BeanFactory、SingletonBeanRegistry、AliasRegistry
AliasRegistry:定义对Alias的简单增删改等操作
xml定义bean的时候是有标签设置别名的
SingletonBeanRegistry:定义了对单例的注册及获取
BeanFactory:定义获取bean及bean的各种属性
中间过程就是增强功能,基本的接口功能就是BeanFactory、SingletonBeanRegistry、AliasRegistry这三块
XmlBeanFactory继承自DefaultListableBeanFactory,DefaultListableBeanFactory是bean加载的核心,是Spring注册以及加载bean的默认实现。 XmlBeanFactory在其基础之上使用了自定义的xml读取器:XmlBeanDefinitionReader,实现了个性化的BeanDefinitionReader
3.0版本的BeanDefinitionReader继承了RescourceLoader接口,这里有必要讨论一下Spring对于外部资源的处理(Spring对外部资源的处理)
代码中的new ClassPathResource(“spring/spring-test.xml”)
ClassPathResource是Resource接口的实现类
看下这段代码的时序图
其中XmlBeanFactory的构造函数调用源码(debug模式)
创建EncodeResource
EncodeResource主要用于对资源文件的编码进行处理。其主要逻辑体现在getReader()方法中,当设置了编码属性的时候Spring会使用相应的编码作为输入流的编码
其中currentResources是记录了已经加载的资源
主要看try部分:
从encodeResource中获取已经封装的Resource之后再获取该Resource的ImputStream,并设置编码格式。
做完这些准备工作,真正的核心部分是在this.doLoadBeanDefinitions()
如果不考虑异常的话那么其实只做了3件事
1.获取对xml文件的验证模式
2.加载xml文件
3.根据返回的Document注册Bean信息
其中第一条在doLoadDocument之中执行:
getValidationModeForResource()
这里需要了解下DTD和XSD的编码规则XML的DTD与XSD验证
我看的是IDEA反编译的源码所以列一下常量定义
validationModeToUser == VALIDATION_AUTO表示自动检测
如果不是自动检测,证明手动设定了验证模式,直接返回。
validationMode是XmlDefinitionReader的一个属性,是可以通过get/set方法进行获取/设定的。
具体的验证xml规范的执行是在detectValidationMode(resource)之中
其实就是判定是不是dta规范,如果不是就是xsd
关键是hasDoctype()
因为DTD声明始终以!DOCTYPE开头,空一格后跟着文档根元素的名称。
例子:
验证模式之后即开始加载Document
Spring3之中是先执行getValidationModeForResource(),而Spring4是先执行
getEntityResolver() 其实没有区别。
现在看下getEntityResolver()
注意使用的是DelegatingEntityResolver。
可以了解下EntityResolver作用
之后是LoadDocument
此时已经把文件转换为Document,之后就是注册bean了
先判定有没有profile属性的设置,再做之后的处理。
两个空的方法, 模板设计模式, 留给子类去实现
核心的处理:
解析的时候分了两类Bean声明:默认/自定义
默认例子:
自定义例子:
对于默认标签的解析使用parseDefaultElement(ele,delegate)
有必要了解下Profile的作用