Spring在启动时,会根据配置(XML、注解或Java配置类)解析并创建对应的 BeanDefinition。这一过程是Spring IoC容器初始化的核心步骤,底层实现包含多个关键组件和流程。以下是具体的原理和步骤:
1.BeanDefinition 的来源
Spring 支持多种配置方式,这些配置会被解析成 BeanDefinition
- XML 配置:解析
<bean>
标签,提取信息。 - 注解配置:扫描类上的注解(如 @Component),提取元数据。
- Java 配置类:读取 @Configuration 类中的方法(如 @Bean 方法)。
无论哪种方式,Spring最终都会将配置信息转换成统一的 BeanDefinition。
2.底层解析的主要组件
2.1 BeanDefinitionRegistry
- 作用:Spring容器的“注册表”,用于存储和管理所有的 BeanDefinition。
- 接口实现:DefaultListableBeanFactory 是最常用的实现类,负责维护Bean的注册。
2.2 Resource 和 ResourceLoader
- 作用:负责加载配置文件(如XML、Properties或注解扫描的路径)。
- 实现:ClassPathResource、FileSystemResource等支持从不同位置加载资源。
2.3 BeanDefinitionReader
- 作用:读取配置并将其解析为 BeanDefinition。
实现:常用的实现类包括:
- XmlBeanDefinitionReader(解析XML配置)
- AnnotatedBeanDefinitionReader(解析注解配置)
- ConfigurationClassBeanDefinitionReader(解析Java配置类)
2.4 BeanDefinitionParser
作用:对特定格式的配置(如XML标签或注解)进行解析,生成对应的 BeanDefinition。
示例:
- XML配置中的
<bean>
标签由 DefaultBeanDefinitionDocumentReader 解析。 - 注解如 @Component 会被 ClassPathBeanDefinitionScanner 处理。
- XML配置中的
3. 核心解析流程
3.1 资源加载
根据用户的配置方式,加载资源:
- XML配置:ResourceLoader 加载XML文件。
- 注解配置:扫描指定包路径(@ComponentScan 指定的范围)。
- Java配置:直接加载 @Configuration 类。
3.2 解析配置为BeanDefinition
XML配置解析
1. 读取XML文档:使用 DocumentLoader 将XML文件解析为DOM树。
2. 解析Bean标签:
• DefaultBeanDefinitionDocumentReader 遍历DOM树,找到 <bean> 标签。
• 每个 <bean> 标签的属性(如 class、scope 等)被解析并封装到一个 GenericBeanDefinition 对象中。
3. 注册BeanDefinition:通过 BeanDefinitionRegistry 将解析的 BeanDefinition 注册到容器中。
注解配置解析
1. 扫描类路径:ClassPathBeanDefinitionScanner 扫描指定包路径,找到类上标注 @Component 的Bean。
2. 生成BeanDefinition:
• 使用 AnnotatedGenericBeanDefinition 保存注解中的元数据。
• 提取注解上的配置信息(如 @Scope、@Lazy)。
3. 注册BeanDefinition:通过 BeanDefinitionRegistry 完成注册。
Java配置类解析
1. 解析 @Configuration 类:ConfigurationClassBeanDefinitionReader 处理带有 @Bean 方法的配置类。
2. 生成BeanDefinition:
• 每个 @Bean 方法对应一个 BeanDefinition。
• 方法返回的类型即为Bean的类型,方法参数用于依赖注入。
3. 注册BeanDefinition:注册到容器中。
3.3 注册到BeanFactory
最终,解析得到的 BeanDefinition 会通过 registerBeanDefinition 方法存储到 DefaultListableBeanFactory 中,等待后续的实例化。
4. 流程总结
以下是Spring解析配置并创建 BeanDefinition 的核心流程:
- 加载资源(XML文件、注解、配置类)。
- 解析配置(使用 BeanDefinitionReader 读取资源)。
- 生成BeanDefinition(封装配置信息到统一的BeanDefinition对象)。
- 注册BeanDefinition(存储到 BeanDefinitionRegistry 中)。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。