Spring 5.3.x 源码:invokeBeanFactoryPostProcessors()详解

这个方法是Refresh()中的一个步骤,这个方法主要处理BeanFactoryPostProcessors接口以及它的子接口BeanDefinitionRegistryPostProcessor

关于执行顺序: (入参)硬编码的BeanFactoryPostProcessors(可能包含BeanFactoryPostProcessors和其子类BeanDefinitionRegistryPostProcessor)>动态配置的**BeanDefinitionRegistryPostProcessor >动态配置的BeanFactoryPostProcessor

什么是BeanFactoryPostProcessor

BeanFactoryPostProcessor顾名思义类工厂后置处理器 ,主要是用来对加载进类工厂的类信息(BeanDefintion)做额外处理的拓展类。加载的时机是:BeanDefintion已经被定义好了,但是在创建对应实例之前。该方法通常用于修改Bean的定义,Bean的属性值等,也可以直接操作类工厂提前初始化Bean

BeanDefintionspring中描述和定义bean的元数据对象,其中包含bean的作用域,生命周期,等等,几乎所有的bean加载进spring都要封装成BeanDefintion,然后交由beanFactory管理并生成对象。

另一个子类BeanDefinitionRegistryPostProcessor,直译BeanDefinitionRegistry后置处理器。继承自BeanFactoryPostProcessor,加载时机:所有的Bean定义即将被加载,但Bean的实例还没被创建时,也就是说,BeanDefinitionRegistryPostProcessorpostProcessBeanDefinitionRegistry方法执行时机先于BeanFactoryPostProcessorpostProcessBeanFactory方法

还有另一个容易搞混的接口:BeanPostProcessor,这个接口对应的处理器执行的时机是Bean开始初始化的先后。

总的来说,这三个接口都是对bean做额外拓展用的,先后调用顺序是:

  1. BeanDefinitionRegistryPostProcessor
  2. BeanFactoryPostProcessor
  3. BeanPostProcessor

方法入参解析

BeanFactory

回顾前面的代码,当前执行中代码的BeanFactory的类型是DefaultListableBeanFactory,其关系类图如下:

从图中可以看出当前BeanFactory继承了BeanDefinitionRegistry,因此下面代码分析中的第一个if是会进去的。

BeanFactoryPostProcessor

什么是BeanFactoryPostProcessor请看第一小节。

BeanFactoryBeanDefinitionRegistry类型时,才会处理其子类BeanDefinitionRegistryPostProcessor的方法postProcessBeanDefinitionRegistry

因此得出结论:

  1. BeanDefinitionRegistryPostProcessor类型处理器只会在BeanFactoryBeanDefinitionRegistry的子类时触发,并且优先级BeanFactoryPostProcessor
  2. BeanFactoryPostProcessor则在任何时候都会触发,即使进入了第一个if,执行的是BeanDefinitionRegistryPostProcessor的方法,但在这个if最后,还是执行了子类继承的父类BeanFactoryPostProcessor的方法
java 复制代码
// 执行所有已经激活的BeanDefinitionRegistryPostProcessor的父类BeanFactoryPostProcessor的方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 执行过滤出的非BeanDefinitionRegistryPostProcessor的BeanFactoryPostProcessor的方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
  1. BeanFactoryPostProcessor 的注入分为两种方式:
    1. 配置注入方式:即通过注解或者xml的方式动态的注入到容器中的BeanFactoryPostProcessor
    2. 硬编码注入方式: 这种方式是直接调用 AbstractApplicationContext#addBeanFactoryPostProcessor 方法将 BeanFactoryPostProcessor 添加到 AbstractApplicationContext#beanFactoryPostProcessors 属性中。其中硬编码注入的BeanFactoryPostProcessor 并不需要也不支持接口排序,而配置注入的方式因为Spring无法保证加载的顺序,所以通过支持PriorityOrderedOrdered排序接口的排序。

代码解析

下面我们来看具体代码:

AbstractApplicationContext#invokeBeanFactoryPostProcessors

AbstractApplicationContext#invokeBeanFactoryPostProcessors 方法内容如下

java 复制代码
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    

    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

实际功能实现还是在PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); 中完成。

getBeanFactoryPostProcessors()

我们先来看看 getBeanFactoryPostProcessors() 得到的是什么

java 复制代码
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();

@Override
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
    Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
    this.beanFactoryPostProcessors.add(postProcessor);
}


public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
    return this.beanFactoryPostProcessors;
}

可以看到 getBeanFactoryPostProcessors() 方法仅仅是将 beanFactoryPostProcessors 集合返回。同时可以看到 beanFactoryPostProcessors 集合是通过addBeanFactoryPostProcessor方法添加的。这就是我们上面提到过的硬编码,所以beanFactoryPostProcessors 实际上是硬编码形式注册的BeanFactoryPostProcessor 类型的处理器集合。

PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

java 复制代码
public static void invokeBeanFactoryPostProcessors(
    ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // 存储已经调用的BeanPostProcessors
    Set<String> processedBeans = new HashSet<>();
    // 当前的类工厂类型是:DefaultListableBeanFactory,他继承了BeanDefinitionRegistry接口
    // 判断是否是BeanDefinitionRegistry的实现类
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
        // 遍历所有从入参beanFactoryPostProcessors,分类并执行(硬编码)
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            // BeanDefinitionRegistryPostProcessor主要是用来为BeanDefinition做额外操作用的
            // 判断是否是BeanDefinitionRegistryPostProcessor,是则遍历执行
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                (BeanDefinitionRegistryPostProcessor) postProcessor;
                // 激活BeanDefinitionRegistryPostProcessor
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                // 记录已经注册的BeanDefinitionRegistryPostProcessor
                registryProcessors.add(registryProcessor);
            }
            else {
                // 如果类型不是BeanDefinitionRegistryPostProcessor,则添加到regularPostProcessors列表
                // 如果不是BeanDefinitionRegistryPostProcessor,那就是其父类BeanFactoryPostProcessor的实现类
                regularPostProcessors.add(postProcessor);
            }
        }


        // 记录当前正在处理的BeanDefinitionRegistryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();


        // 首先,调用实现 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor。
        // 获取所有动态配置的BeanDefinitionRegistryPostProcessor
        // getBeanNamesForType是从配置中获取的对应bean的方法
        String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        // 对应实现 PriorityOrdered 的 bean 进行排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        // 执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry方法
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
        // 清理缓存
        currentRegistryProcessors.clear();


        // 接下来,调用实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessor 。
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        // 遍历所有 postProcessorNames
        for (String ppName : postProcessorNames) {
            // 获取实现了Ordered接口的BeanDefinitionRegistryPostProcessor,并且判断了是否已经是执行过的bean
            // processedBeans 存储的是已经执行过的bean
            // 如果一个BeanDefinitionRegistryPostProcessor同时实现了 PriorityOrdered 接口和 Ordered 接口,那么PriorityOrdered的优先级更高
            // 因为 PriorityOrdered接口的实现类先执行,而Ordered接口后执行
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        // 对应实现 PriorityOrdered 的 bean 进行排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        // 执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry方法
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
        // 清理缓存
        currentRegistryProcessors.clear();


        // 最后按顺序执行所有没有实现排序接口的BeanDefinitionRegistryPostProcessors
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 不判断是否实现接口,而是判断是否执行过
                if (!processedBeans.contains(ppName)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }

            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
            currentRegistryProcessors.clear();
        }

        // 现在,调用所有已处理过的处理器父类BeanFactoryPostProcessors的"postProcessBeanFactory"回调函数
        // 目的是处理即重写了BeanFactoryPostProcessors和BeanDefinitionRegistryPostProcessor方法的类
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        // 执行第一个for遗留下来的BeanFactoryPostProcessors
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
        // 如果工厂类不是BeanDefinitionRegistry的实例,则按照BeanFactoryPostProcessors执行
        // 因为此处的BeanFactoryPostProcessors是从参数获取的,属于硬编码
        // 因此这里面的BeanFactoryPostProcessors是按照数组顺序执行的
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }


    // 获取所有BeanFactoryPostProcessors的配置
    String[] postProcessorNames =
    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);


    // 同样按照实现的排序接口顺序执行
    // 分别存储实现PriorityOrdered,Ordered接口以及没实现任何排序结构的信息
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    // 通过for循环对信息进行分类
    for (String ppName : postProcessorNames) {
        if (processedBeans.contains(ppName)) {
            // skip - already processed in first phase above
        }
        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 按照对应的PriorityOrdered接口排序后再执行BeanFactoryPostProcessors
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // 按照对应的Ordered接口排序后再执行BeanFactoryPostProcessors
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);


    // 激活所有其它没有实现排序接口的BeanFactoryPostProcessors
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    // Clear cached merged bean definitions since the post-processors might have
    // modified the original metadata, e.g. replacing placeholders in values...
    beanFactory.clearMetadataCache();
}

流程图

相关推荐
weixin_456904273 小时前
Spring Boot 用户管理系统
java·spring boot·后端
cyforkk4 小时前
Spring 异常处理器:从混乱到有序,优雅处理所有异常
java·后端·spring·mvc
程序员爱钓鱼5 小时前
Go语言实战案例-开发一个Markdown转HTML工具
前端·后端·go
桦说编程5 小时前
爆赞!完全认同!《软件设计的哲学》这本书深得我心
后端
thinktik5 小时前
还在手把手教AI写代码么? 让你的AWS Kiro AI IDE直接读飞书需求文档给你打工吧!
后端·serverless·aws
老青蛙8 小时前
权限系统设计-用户设计
后端
echoyu.8 小时前
消息队列-初识kafka
java·分布式·后端·spring cloud·中间件·架构·kafka
yuluo_YX8 小时前
Go Style 代码风格规范
开发语言·后端·golang
David爱编程8 小时前
从 JVM 到内核:synchronized 与操作系统互斥量的深度联系
java·后端