前戏
Spring 提供了一个读取配置文件的接口:BeanDefinitionReader
,理论上读取 Spring 的配置文件需要实现这个接口,但也不强制。
Note that a bean definition reader does not have to implement this interface. It only serves as suggestion for bean definition readers that want to follow standard naming conventions.
它有三个主要的实现类:
分别表示:
- XmlBeanDefinitionReader:具体实现类,可以从 XML 文件读取 Bean 定义信息;
- PropertiesBeanDefinitionReader:具体实现类,可以从 Properties 文件读取 Bean 定义信息;
- GroovyBeanDefinitionReader:具体实现类,可以读取 Groovy 语言写的 Bean 的定义信息。
因为读取配置信息非必须实现这个接口,所以你还可以看到其他读取 Bean 的定义信息的类:
- JdbcBeanDefinitionReader
- AnnotatedBeanDefinitionReader
- ConfigurationClassBeanDefinitionReader
首先通过接口和抽象类了解下都需要做什么操作?
大概的意思:从某处加载定义信息,解析成 BeanDefinition,注册进 BeanDefinitionRegistry;
AbstractBeanDefinitionReader 对这个过程进行了实现,把 loadBeanDefinitions(Resource resource)
交给了子类去处理。当然这个过程还包括 Bean 定义校验,SAX 对 XML 的解析,处理环境变量等;
BeanDefinitionRegistry 上面还有一个接口 AliasRegistry,表示利用别名操作注册信息;
这个Bean注册意思:解析好的 BeanDefinition 相关信息存储到一个 Map 容器中。
具体过程
类流转示意图:
Bean 定义具体是如何读取注册的?这个时候看源码中的单元测试最合适!
@Test
public void withOpenInputStreamAndExplicitValidationMode() {
SimpleBeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
Resource resource =
new InputStreamResource(getClass().getResourceAsStream("test.xml"));
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(registry);
reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_DTD);
reader.loadBeanDefinitions(resource);
testBeanDefinitions(registry);
}