ApplicationContext 解析 Bean 定义的过程,实际上是其内部的 BeanFactory(通常是 DefaultListableBeanFactory)与各种 BeanDefinitionReader 和解析器协同工作的结果。这个过程主要发生在 ApplicationContext 的 refresh() 方法中,特别是 obtainFreshBeanFactory() 和 invokeBeanFactoryPostProcessors() 阶段。
以下是 ApplicationContext 解析 Bean 定义的详细步骤,以及涉及到的主要组件:
1. 加载资源 (Resource Loading):
ResourceLoader:ApplicationContext接口继承了ResourceLoader接口,可以使用getResource()方法加载各种资源,例如:ClassPathResource: 从类路径加载资源。FileSystemResource: 从文件系统加载资源。UrlResource: 从 URL 加载资源。
- 示例:
// 使用 ClassPathXmlApplicationContext ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // 从类路径加载 // 使用 FileSystemXmlApplicationContext ApplicationContext context = new FileSystemXmlApplicationContext("config/applicationContext.xml"); // 从文件系统加载 // 使用 ResourceLoader Resource resource = context.getResource("classpath:applicationContext.xml");
2. 读取 Bean 定义 (Bean Definition Reading):
BeanDefinitionReader: 负责读取 Bean 定义的资源(如 XML 文件、注解配置类)并将其转换为BeanDefinition对象。- 主要实现类:
XmlBeanDefinitionReader: 用于读取 XML 配置文件。AnnotatedBeanDefinitionReader: 用于注册带有注解的 Bean 类 (如@Component,@Configuration).ClassPathBeanDefinitionScanner: 扫描类路径,查找带有特定注解的类,并生成BeanDefinition。 通常与@ComponentScan或<context:component-scan>配合使用。
- 读取流程:
ApplicationContext(通常在obtainFreshBeanFactory()阶段) 会创建一个或多个BeanDefinitionReader实例。BeanDefinitionReader使用ResourceLoader加载配置文件。BeanDefinitionReader解析配置文件,并将 Bean 定义转换为BeanDefinition对象。BeanDefinitionReader将BeanDefinition对象注册到BeanDefinitionRegistry中(通常是DefaultListableBeanFactory)。
3. XML 配置的解析 (XmlBeanDefinitionReader):
XmlBeanDefinitionReader:- 使用 SAX 或 DOM 解析器将 XML 文件解析为
Document对象。 BeanDefinitionDocumentReader(通常是DefaultBeanDefinitionDocumentReader) 遍历Document中的元素。<beans>元素: 解析根元素。<import>元素: 递归地加载和解析导入的 XML 文件。<bean>元素:BeanDefinitionParserDelegate解析<bean>元素,提取id、class、scope、constructor-arg、property等属性,并创建相应的BeanDefinition对象(通常是GenericBeanDefinition)。- 自定义命名空间元素 (如
<context:component-scan>,<aop:config>):BeanDefinitionParserDelegate查找相应的NamespaceHandler,并调用其parse方法来解析元素。NamespaceHandler可能会使用自定义的BeanDefinitionParser来解析特定的元素。
- 使用 SAX 或 DOM 解析器将 XML 文件解析为
NamespaceHandler: 用于解析自定义的 XML 命名空间和元素。BeanDefinitionParser: 用于解析特定的 XML 元素并生成BeanDefinition。
4. 注解配置的解析 (AnnotatedBeanDefinitionReader 和 ClassPathBeanDefinitionScanner):
-
AnnotatedBeanDefinitionReader:- 注册单个带有注解的 Bean 类。
- 处理
@Configuration、@Bean、@Import、@DependsOn、@Primary、@Lazy、@Role、@Description等注解。
-
ClassPathBeanDefinitionScanner:- 扫描类路径,查找带有
@Component、@Service、@Repository、@Controller、@Configuration等注解的类。 - 为每个找到的类创建一个
ScannedGenericBeanDefinition对象(AnnotatedBeanDefinition的实现类)。 - 使用
AnnotationBeanNameGenerator根据注解生成 Bean 的名称。
- 扫描类路径,查找带有
-
ConfigurationClassParser:- 解析
@Configuration注解的配置类。 - 处理
@Bean、@Import、@ComponentScan、@PropertySource、@ImportResource等注解。@Bean方法: 为每个@Bean方法创建一个BeanDefinition对象(ConfigurationClassBeanDefinition),并将其注册到容器中。@Import注解: 递归地解析@Import导入的配置类或ImportSelector、ImportBeanDefinitionRegistrar。@ComponentScan注解: 触发ClassPathBeanDefinitionScanner扫描指定的包。
- 解析
-
AutowiredAnnotationBeanPostProcessor:- 处理
@Autowired、@Value、@Inject等注解,实现依赖注入。
- 处理
5. 注册 Bean 定义 (Bean Definition Registration):
BeanDefinitionRegistry:ApplicationContext内部的BeanFactory(通常是DefaultListableBeanFactory)实现了BeanDefinitionRegistry接口,用于存储和管理 Bean 定义。- 注册过程:
BeanDefinitionReader将解析得到的BeanDefinition对象注册到BeanDefinitionRegistry中。BeanDefinitionRegistry将BeanDefinition对象存储在一个Map中(键为 Bean 的名称,值为BeanDefinition对象)。
6. BeanFactoryPostProcessor 的处理:
* 在BeanDefinition加载完, 实例化Bean之前, 会调用BeanFactoryPostProcessor.
* BeanFactoryPostProcessor 可以修改 BeanFactory 的配置元数据(例如,修改 BeanDefinition 的属性)。
* BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,它可以在Bean 定义加载完成后,但在 Bean 实例化之前执行,允许添加、删除或修改 Bean 定义。
总结流程图:
+---------------------+ +---------------------+ +-----------------------+
| ApplicationContext |---->| ResourceLoader |---->| Resource | (加载配置文件)
+---------------------+ +---------------------+ +-----------------------+
|
V
+-----------------------+
| BeanDefinitionReader | (读取 Bean 定义)
+-----------------------+
|
+-------------------------------------------------+-------------------------------------------------+
| | |
V V V
+---------------------+ +---------------------------+ +-----------------------------+
|XmlBeanDefinitionReader| | AnnotatedBeanDefinitionReader| | ClassPathBeanDefinitionScanner | (解析配置)
+---------------------+ +---------------------------+ +-----------------------------+
| | |
| 解析 XML | 处理 @Configuration, @Bean 等 | 扫描类路径, 查找 @Component 等 |
| - <beans> | - 注册 Bean 类 | - 生成 ScannedGenericBeanDefinition |
| - <import> | | |
| - <bean> -> BeanDefinitionParserDelegate | | |
| - 自定义命名空间 -> NamespaceHandler | | |
V V V
+---------------------+ +-----------------------+ +-----------------------+
| BeanDefinition | | BeanDefinition | | BeanDefinition | (Bean 定义对象)
+---------------------+ +-----------------------+ +-----------------------+
| | |
+-------------------------------------------------+-------------------------------------------------+
|
V
+-----------------------+
| BeanDefinitionRegistry | (注册 Bean 定义)
+-----------------------+
|
V
+-----------------------+
| BeanFactory | (Spring IoC 容器)
+-----------------------+
关键点:
ApplicationContext负责协调整个 Bean 定义解析过程。ResourceLoader负责加载配置文件。BeanDefinitionReader负责读取配置文件并将其转换为BeanDefinition对象。- 不同的
BeanDefinitionReader实现类用于处理不同的配置格式(XML、注解)。 BeanDefinitionRegistry负责存储和管理BeanDefinition对象。BeanFactoryPostProcessor(包括BeanDefinitionRegistryPostProcessor) 可以在 Bean 实例化之前修改BeanFactory的配置元数据。- Spring Boot 简化了配置, 但底层仍然使用这些组件来解析 Bean 定义.

1361

被折叠的 条评论
为什么被折叠?



