ApplicationContext 如何解析 Bean 定义

ApplicationContext 解析 Bean 定义的过程,实际上是其内部的 BeanFactory(通常是 DefaultListableBeanFactory)与各种 BeanDefinitionReader 和解析器协同工作的结果。这个过程主要发生在 ApplicationContextrefresh() 方法中,特别是 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 对象。
    • BeanDefinitionReaderBeanDefinition 对象注册到 BeanDefinitionRegistry 中(通常是 DefaultListableBeanFactory)。

3. XML 配置的解析 (XmlBeanDefinitionReader):

  • XmlBeanDefinitionReader:
    • 使用 SAX 或 DOM 解析器将 XML 文件解析为 Document 对象。
    • BeanDefinitionDocumentReader (通常是 DefaultBeanDefinitionDocumentReader) 遍历 Document 中的元素。
      • <beans> 元素: 解析根元素。
      • <import> 元素: 递归地加载和解析导入的 XML 文件。
      • <bean> 元素: BeanDefinitionParserDelegate 解析 <bean> 元素,提取 idclassscopeconstructor-argproperty 等属性,并创建相应的 BeanDefinition 对象(通常是 GenericBeanDefinition)。
      • 自定义命名空间元素 (如 <context:component-scan>, <aop:config>): BeanDefinitionParserDelegate 查找相应的 NamespaceHandler,并调用其 parse 方法来解析元素。NamespaceHandler 可能会使用自定义的 BeanDefinitionParser 来解析特定的元素。
  • NamespaceHandler: 用于解析自定义的 XML 命名空间和元素。
  • BeanDefinitionParser: 用于解析特定的 XML 元素并生成 BeanDefinition

4. 注解配置的解析 (AnnotatedBeanDefinitionReaderClassPathBeanDefinitionScanner):

  • 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 导入的配置类或 ImportSelectorImportBeanDefinitionRegistrar
      • @ComponentScan 注解: 触发 ClassPathBeanDefinitionScanner 扫描指定的包。
  • AutowiredAnnotationBeanPostProcessor:

    • 处理 @Autowired@Value@Inject 等注解,实现依赖注入。

5. 注册 Bean 定义 (Bean Definition Registration):

  • BeanDefinitionRegistry: ApplicationContext 内部的 BeanFactory(通常是 DefaultListableBeanFactory)实现了 BeanDefinitionRegistry 接口,用于存储和管理 Bean 定义。
  • 注册过程:
    • BeanDefinitionReader 将解析得到的 BeanDefinition 对象注册到 BeanDefinitionRegistry 中。
    • BeanDefinitionRegistryBeanDefinition 对象存储在一个 Map 中(键为 Bean 的名称,值为 BeanDefinition 对象)。

6. BeanFactoryPostProcessor 的处理:
* 在BeanDefinition加载完, 实例化Bean之前, 会调用BeanFactoryPostProcessor.
* BeanFactoryPostProcessor 可以修改 BeanFactory 的配置元数据(例如,修改 BeanDefinition 的属性)。
* BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor的子接口,它可以在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 定义.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值