【Spring】简述@Configuration配置类注册BeanDefinition到Spring容器的过程

本文详细探讨了Spring框架中@Configuration配置类如何注册BeanDefinition到Spring容器的过程,涉及ConfigurationClassPostProcessor、ConfigurationClassParser和ConfigurationClassBeanDefinitionReader的作用。文章通过源码分析,解释了从配置类的解析、Bean定义的读取到注册的完整流程,对理解Spring启动过程和配置处理有重要帮助。
摘要由CSDN通过智能技术生成

概述

本文以SpringBoot应用为基础,尝试分析基于注解@Configuration的配置类是如何向Spring容器注册BeanDefinition的过程

其中主要分析了 ConfigurationClassPostProcessor 这个BeanDefinitionRegistryPostProcessor 即Bean定义注册后置处理器,在Spring启动过程中对@Configuration配置类的处理,主要体现在 解析并发现所有配置类,处理配置类的相关逻辑(如配置类上的@ComponentScan、@Import、@Bean注解等),注册其中的BeanDefinition

SpringBoot版本:2.0.9.RELEASE

Spring版本:5.0.13.RELEASE

ConfigurationClassPostProcessor如何被引入

首先看一下ConfigurationClassPostProcessor的类继承关系

从红框中可以看出ConfigurationClassPostProcessorBeanDefinitionRegistryPostProcessor接口的实现类,即是一个Bean定义注册的后置处理器,会在Spring容器启动时被调用,具体时机为

// 调用链
AbstractApplicationContext.refresh()
    => invokeBeanFactoryPostProcessors()
    => PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()

invokeBeanFactoryPostProcessors()会先调用所有的BeanDefinitionRegistryPostProcessor之后,再调用所有的BeanFactoryPostProcessor

ConfigurationClassPostProcessor又是如何被引入Spring的呢??

SpringBoot应用会在ApplicationContext应用上下文被创建的构造函数中new AnnotatedBeanDefinitionReader这个用于注册基于注解的BeanDefinition的Reader,在其构造中又会调用AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)使用工具类向Spring容器中注册一些所谓的注解配置处理器,其中就包含ConfigurationClassPostProcessor

// ConfigurationClassPostProcessor被注册
AnnotationConfigServletWebServerApplicationContext构造
    => new AnnotatedBeanDefinitionReader(registry)
        => AnnotationConfigUtils.registerAnnotationConfigProcessors(registry)
            => 注册ConfigurationClassPostProcessor到Spring容器

ConfigurationClassPostProcessor处理过程简述

首先,ConfigurationClassPostProcessor后置处理器的处理入口为postProcessBeanDefinitionRegistry()方法。其主要使用了ConfigurationClassParser配置类解析器解析@Configuration配置类上的诸如@ComponentScan@Import@Bean等注解,并尝试发现所有的配置类;还使用了ConfigurationClassBeanDefinitionReader注册所发现的所有配置类中的所有Bean定义;结束执行的条件是所有配置类都被发现和处理,相应的bean定义注册到容器

大致流程如下:

1、通过BeanDefinitionRegistry查找当前Spring容器中所有BeanDefinition

2、通过ConfigurationClassUtils.checkConfigurationClassCandidate() 检查BeanDefinition是否为 “完全配置类”“简化配置类”,并对配置类做标记,放入集合待后续处理

Spring配置类的分类可以 参考

3、通过 ConfigurationClassParser解析器 parse解析配置类集合,尝试通过它们找到其它配置类

4、使用 ConfigurationClassBeanDefinitionReader 注册通过所发现的配置类中找到的所有beanDefinition

5、处理完一轮配置类后,查看BeanDefinitionRegistry中是否存在新加载的且还未被处理过的 “完全配置类”“简化配置类”,有的话继续上面步骤

其中第3、4步后面重点分析

ConfigurationClassParser#parse():解析构建配置类

对于SpringBoot应用来说,参与解析的种子配置文件即为SpringBoot的Application启动类

解析构建配置类流程

通过ConfigurationClassParser解析器parse解析配置类集合,尝试通过它们找到其它配置类

  • 循环解析所有配置类 ConfigurationClassParser#processConfigurationClass()

    • 根据@Conditional的ConfigurationPhase.PARSE_CONFIGURATION阶段条件判断是否跳过配置类

      注意:有些@Conditional是在当前这个PARSE_CONFIGURATION解析配置阶段使用的,有些是在REGISTER_BEAN注册beanDefinition阶段使用的

    • 【重点】调用ConfigurationClassParser#doProcessConfigurationClass()循环解析配置类,直到不

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值