Spring源码解析(二) 调用Bean工厂处理器对象
SunRan

前言

BeanFactoryPostProcessor 是 Spring 中很重要的一种机制,本文主要介绍了 BeanFactoryPostProcessor 的注册与执行。

该步骤相比较创建 BeanFactory并注册 BeanDefinition要简单清晰的多,没有过多的调核心方法 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());只有两百多行。

基本概念

  • BeanFactoryPostProcessor

    BeanFactory在创建完成后的后置处理器,可以自定义一些业务代码,可用于:修改BeanDefinition,提前CreateBean。其实和 BeanPostProcessor相似。

  • BeanDefinitionRegistryPostProcessor

    他是 BeanFactoryPostProcessor的子接口,相比较他的父接口多了一个执行方法 postProcessBeanDefinitionRegistry

    优先级要大于 BeanFactoryPostProcessor

  • PriorityOrderedOrdered

    其实都是用于定义优先级的。

优先级 在本方法中非常重要,看似简单的代码被拉长到了两百多行就是因为优先级导致的。

上面概念中多次提到优先级这个词,下面用简单暴力的话解答一下。

  • BeanDefinitionRegistryPostProcessor 的优先级一定大于 BeanFactoryPostProcessor ,就算天塌了也是先执行 BeanDefinitionRegistryPostProcessor
  • 被定义 PriorityOrderedBean 优先级一定大于 Ordered 的对象。
  • N个对象如果同样被 PriorityOrdered 或者 Ordered 定义,则比较其值大小。

抽象流程

三、prepareBeanFactory()

图片比较大,建议放大后对比源码观看。

如果用简单的话总结执行步骤:

  • 第一步:执行预设的 BeanDefinitionRegistryPostProcessor 对象(大部分情况下没有预设对象)
  • 第二步:执行现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
  • 第三步:执行实现了Ordered接口的BeanDefinitionRegistryPostProcessor
  • 第四步:执行剩余的BeanDefinitionRegistryPostProcessor
  • 第五步:查询实现 BeanFactoryPostProcessor 接口的对象,根据是否已执行、是否实现PriorityOrdered或Ordered接口去分类,分别加入不同的列表,用于最后统一的执行
  • 第六步:统一遍历执行前面收集到的处理器对象
  • 第七步:执行结束,清理元数据缓存

如何预设的处理器对象

前面有说过,在 invokeBeanFactoryPostProcessors中将 getBeanFactoryPostProcessors()作为参数传递给了 invokeBeanFactoryPostProcessors

只需要在执行此步骤之前将前置处理器添加到 BeanFactoryPostProcessors中即可(⚠️ 此处的 BeanFactoryPostProcessors有一个 s,是一个列表)。

例如:

  • postProcessBeanFactory是一个预留的方法,里面没有实现,我们只需要重写该方法即可

    1
    2
    3
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    this.addBeanFactoryPostProcessor(new PreBeanFactoryPostProcessor());
    }

    其中 PreBeanFactoryPostProcessor是自己实现的一个处理器对象。

  • 当然也可以直接修改源码在任何地方执行 this.addBeanFactoryPostProcessor

源码

其实整个流程走下来,发现这块源码没啥难的就不详细介绍了,结合流程图和官方注释问题不大。

总结

一句话概括:就一个执行BeanFactory处理器对象的方法,只不过因为优先级的问题搞得有点复杂。

  • 本文标题:Spring源码解析(二) 调用Bean工厂处理器对象
  • 本文作者:SunRan
  • 创建时间:2022-01-21 11:10:39
  • 本文链接:https://lksun.cn/2022/01/21/Spring源码解析-二-调用BeanFactory处理器/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论