【spring学习笔记 七】ConfigurationClassPostProcessor详解

导读:本篇文章讲解 【spring学习笔记 七】ConfigurationClassPostProcessor详解,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,原文地址:Java

也许你感觉自己的努力总是徒劳无功,但不必怀疑,你每天都离顶点更进一步。今天的你离顶点还遥遥无期。但你通过今天的努力,积蓄了明天勇攀高峰的力量。加油!

概览

ConfigurationClassPostProcessor.class主要解决的问题就是去处理spring定义的一些配置注解,例如@Configuration@Import@ComponentScan@Bean等。

ConfigurationClassPostProcessor

在这里插入图片描述

  1. 实现了BeanDefinitionRegistryPostProcessor(BeanFactoryPostProcessor的子类)。
  2. PriorityOrdered,该类优先执行。
  3. ResourceLoaderAware,获取资源加载器。
  4. BeanClassLoaderAware,获取类加载器。
  5. EnviromentAware,获取环境信息。

通过类的实现接口,我们可以大致判断出其主要的处理逻辑在BeanDefinitionRegistryPostProcessor的实现方法中。

由前面的文章我们能知道,BeanDefinitionRegistryPostProcessor接口与BeanFactoryPostProcessor接口的执行顺序是,BeanDefinitionRegistryPostProcessor优先于BeanFactoryPostProcessor

执行顺序详见 【spring学习笔记 三】invokeBeanFactoryPostProcessors()

所以接下来我们先来看看BeanDefinitionRegistryPostProcessor的方法。

postProcessBeanDefinitionRegistry()

在这里插入图片描述
通过注册器获取当前注册器中所有的注册信息。并且找到有@Configuration注解的类。
这里的时间节点非常重要。(这时候只有一些内置类和启动类在注册器中,因此@SpringBootApplication中必定有@Configuration注解)。如下图

详见,前面的文章。

在这里插入图片描述
下面就是对找到的类进行解释加载
在这里插入图片描述

parse()

在这里插入图片描述
在这里插入图片描述
这个方法中就是对@PropertySource@ComponentScan@Import@ImportSource@Bean注解进行解释。

@Component

在这里插入图片描述
如果类上面有@Component注解,就扫描类的成员变量所属的类。然后继续这个逻辑。

@PropertySource

在这里插入图片描述
对于@PropertySource注解,就是将其信息加载进来,并且放入Enviroment中,位置是在最后(第一个加载的在最后)。

@ ComponentScan,@ComponentScans

在这里插入图片描述
解析路径,并扫描路径下的bean。符合规范的就封装成BeanDefinitionHolder(就是有@Component注解的类,我们在使用中用到的@Service@Controller都继承于@Component),在后续的步骤中在进行注册。

@Import

在这里插入图片描述
对于@Import注解的处理方式主要分为3类:

  1. 实现了ImportSelector接口
  2. 实现了ImportBeanDefinitionRegistrar接口
  3. 其它

实现ImportSelector

在这里插入图片描述
对于实现了ImportSelector接口的处理方式又分为2类:

  1. 实现了ImportSelector
  2. 实现了其子类DeferredImportSelector()(这个类由于了解的不深,就不聊了。)

对于1来说,就是执行接口的实现方法selectImports(),然后继续解析导入的类。

实现ImportBeanDefinitionRegistrar接口

在这里插入图片描述
分为2步:

  1. 实例化该类。
  2. 并将其添加到自己的集合中(后续加载的时候在进行执行)。

@Bean

在这里插入图片描述
也是分两步:

  1. 找到所有有@Bean注解的方法(正常范围内),并将其信息封装成MethodMetadata。
  2. 将消息放入自己的集合中(后续加载的时候在进行操作)。

到这里,解析工作已经完毕了。后面的就是进行加载了。

load()

在这里插入图片描述
这一步就比较简单了,就是将前面一系列准备好的东西进行注册或访问。

前面实现了ImportBeanDefinitionRegistrar接口的类,触发时间点就是在这里。

postProcessBeanFactory()

这个后置
主要工作有2步:

  1. 对由@Configuration注解的类进行增强。
  2. 添加一个BeanPostProcessor处理器。

先来看看它对@Configuration类做了怎么样的增强。

enhanceConfigurationClasses()

在这里插入图片描述
首先找到所有的@Configuration类,然后进行增强。
在这里插入图片描述
在这里插入图片描述
增强的方式有3种:

  1. BeanMethodInterceptor
  2. BeanFactoryAwareMethodInterceptor
  3. NoOp.INSTANCE(什么都不处理)

我们先来看看第一种BeanMethodInterceptor

BeanMethodInterceptor

触发条件

在这里插入图片描述
类不是Object,并且方法不能是setBeanFactory,并且方法上面有@Bean注解。

作用

在这里插入图片描述
它主要是用来控制bean的生成方式,主要分为三种

  1. FactoryBean
  2. 普通Bean

对于1,
将会按照FactoryBean的加载方式进行,也就是通过访问getObject方法,而不是通过从容器中获取。
对于2,
分为2类,第一类就是访问的方法与根方法一致。也就是有自身发起,访问自身。
在这里插入图片描述
这种情况,就是直接访问本身方法就行了。
在这里插入图片描述

第二类就是由其它方法发起
在这里插入图片描述
针对这种情况将会,除了访问本身的方法,还会将createA与createB这两个Bean绑定在一起。
在这里插入图片描述

BeanFactoryAwareMethodInterceptor

触发条件

在这里插入图片描述
访问的方法是setBeanFactory(),并且参数只有一个类型为BeanFactory,类实现了BeanFactoryAware。

作用

在这里插入图片描述
将BeanFactory对象放到对象中的第一个属性中。(这没搞明白。)
其它就没有操作了。

总结

ConfigurationClassPostProcessor这类主要就是去处理@Configuration中的一些配置信息,比如@Import@ComponetScan等。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/121865.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!