(1)容器的基本实现

定义一个Bean
(1)容器的基本实现

在xml配置文件之中配置好
(1)容器的基本实现

使用BeanFactory获取Bean
(1)容器的基本实现

使用到了XmlBeanFactory,看XmlBeanFactory的类结构图
(1)容器的基本实现

最上层是3个接口BeanFactory、SingletonBeanRegistry、AliasRegistry
AliasRegistry:定义对Alias的简单增删改等操作
(1)容器的基本实现

xml定义bean的时候是有标签设置别名的

SingletonBeanRegistry:定义了对单例的注册及获取
(1)容器的基本实现

BeanFactory:定义获取bean及bean的各种属性

(1)容器的基本实现

中间过程就是增强功能,基本的接口功能就是BeanFactory、SingletonBeanRegistry、AliasRegistry这三块

(1)容器的基本实现

XmlBeanFactory继承自DefaultListableBeanFactory,DefaultListableBeanFactory是bean加载的核心,是Spring注册以及加载bean的默认实现。 XmlBeanFactory在其基础之上使用了自定义的xml读取器:XmlBeanDefinitionReader,实现了个性化的BeanDefinitionReader

(1)容器的基本实现

3.0版本的BeanDefinitionReader继承了RescourceLoader接口,这里有必要讨论一下Spring对于外部资源的处理(Spring对外部资源的处理

代码中的new ClassPathResource(“spring/spring-test.xml”)
ClassPathResource是Resource接口的实现类
(1)容器的基本实现

看下这段代码的时序图

(1)容器的基本实现

其中XmlBeanFactory的构造函数调用源码(debug模式)
(1)容器的基本实现
(1)容器的基本实现
创建EncodeResource
EncodeResource主要用于对资源文件的编码进行处理。其主要逻辑体现在getReader()方法中,当设置了编码属性的时候Spring会使用相应的编码作为输入流的编码
(1)容器的基本实现

(1)容器的基本实现

(1)容器的基本实现
其中currentResources是记录了已经加载的资源
主要看try部分:
从encodeResource中获取已经封装的Resource之后再获取该Resource的ImputStream,并设置编码格式。
做完这些准备工作,真正的核心部分是在this.doLoadBeanDefinitions()
(1)容器的基本实现

如果不考虑异常的话那么其实只做了3件事
1.获取对xml文件的验证模式
2.加载xml文件
3.根据返回的Document注册Bean信息

其中第一条在doLoadDocument之中执行:
(1)容器的基本实现
getValidationModeForResource()

这里需要了解下DTD和XSD的编码规则XML的DTD与XSD验证

我看的是IDEA反编译的源码所以列一下常量定义
(1)容器的基本实现

(1)容器的基本实现
validationModeToUser == VALIDATION_AUTO表示自动检测
如果不是自动检测,证明手动设定了验证模式,直接返回。
(1)容器的基本实现
validationMode是XmlDefinitionReader的一个属性,是可以通过get/set方法进行获取/设定的。

具体的验证xml规范的执行是在detectValidationMode(resource)之中
(1)容器的基本实现

(1)容器的基本实现

其实就是判定是不是dta规范,如果不是就是xsd
关键是hasDoctype()

(1)容器的基本实现
因为DTD声明始终以!DOCTYPE开头,空一格后跟着文档根元素的名称。
例子:

验证模式之后即开始加载Document
Spring3之中是先执行getValidationModeForResource(),而Spring4是先执行
getEntityResolver() 其实没有区别。

现在看下getEntityResolver()

(1)容器的基本实现

注意使用的是DelegatingEntityResolver。
可以了解下EntityResolver作用
之后是LoadDocument

(1)容器的基本实现
此时已经把文件转换为Document,之后就是注册bean了
(1)容器的基本实现

(1)容器的基本实现

(1)容器的基本实现

(1)容器的基本实现

(1)容器的基本实现

(1)容器的基本实现

先判定有没有profile属性的设置,再做之后的处理。
(1)容器的基本实现

两个空的方法, 模板设计模式, 留给子类去实现

核心的处理:
(1)容器的基本实现

解析的时候分了两类Bean声明:默认/自定义
默认例子:
(1)容器的基本实现

自定义例子:
(1)容器的基本实现

对于默认标签的解析使用parseDefaultElement(ele,delegate)

有必要了解下Profile的作用