【spring】Spring IoC源码学习:invokeBeanFactoryPostProcessors 详解

1. 概述

本方法会实例化和调用所有 BeanFactoryPostProcessor(包括其子类 BeanDefinitionRegistryPostProcessor,子类优先级高,会优先处理)。

BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它

BeanFactoryPostProcessor 详细用法参见《Spring的BeanFactoryPostProcessor和BeanPostProcessor》

BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor接口(比 BeanFactoryPostProcessor 具有更高的优先级执行),那么一定要做些事情,子接口前缀BeanDefinitionRegistry顾名思义,负责BeanDefinition的注册,主要用来在常规的 BeanFactoryPostProcessor 检测开始之前注册其他 bean 定义。

特别是,你可以通过 BeanDefinitionRegistryPostProcessor 来注册一些常规的 BeanFactoryPostProcessor,因为此时所有常规的 BeanFactoryPostProcessor 都还没开始被处理。
在这里插入图片描述

注:这边的 “常规 BeanFactoryPostProcessor” 主要用来跟 BeanDefinitionRegistryPostProcessor 区分。

因此,invokeBeanFactoryPostProcessors()主要功能就是寻找实现BeanFactoryPostProcessor的子类,并调用他们的重载方法,比如子类BeanDefinitionRegistryPostProcessor 负责注册bean(仅仅是注册,不是实例化,但是也需要提前实例化一部分bean)。

2. invokeBeanFactoryPostProcessors

首先我们回到 AbstractApplicationContext.refresh() 方法,找到代码:invokeBeanFactoryPostProcessors(beanFactory) ,单击该行代码跳转到具体的实现。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    
    
    // 1.getBeanFactoryPostProcessors(): 拿到当前应用上下文beanFactoryPostProcessors变量中的值
    // 2.invokeBeanFactoryPostProcessors(): 实例化并调用所有已注册的BeanFactoryPostProcessor
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
 
    // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
    // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    
    
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

1.拿到当前应用上下文 beanFactoryPostProcessors 变量中的值,见代码块1详解。

2.实例化并调用所有已注册的 BeanFactoryPostProcessor,见代码块2详解。

1.1 代码块1:getBeanFactoryPostProcessors()

public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
    
    
    //成员变量,List<BeanFactoryPostProcessor>结构的集合
    return this.beanFactoryPostProcessors;
}

这边 getBeanFactoryPostProcessors() 会拿到当前应用上下文中已经注册的 BeanFactoryPostProcessor,在默认情况下,this.beanFactoryPostProcessors ()是返回空的。

如何添加自定义 BeanFactoryPostProcessor 到 this.beanFactoryPostProcessors 变量中了?

如果还有印象的话,我们在 Spring IoC:refresh前的环境准备 中的代码块12介绍过 customizeContext 方法,该方法是 Spring 提供给开发者的一个扩展点,用于自定义应用上下文,并且在 refresh() 方法前就被调用。在这边就可以通过该方法来添加自定义的 BeanFactoryPostProcessor。

简单来说,内置的BeanFactoryPostProcessor实现类或者定义@Component(等待spring扫描的实现了BeanFactoryPostProcessor接口的)的实现类,不在 this.beanFactoryPostProcessors 变量中,该变量存储的是其他方式定义的BeanFactoryPostProcessor。

简单的实现如下:

1.新建一个 ApplicationContextInitializer 的实现类 SpringApplicationContextInitializer ,并在 initialize 方法中写我们的逻辑。

package com.joonwhee.open.demo.spring;
 
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
 
/**
 * @author joonwhee
 * @date 2019/1/19
 */
public class SpringApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    
    
 
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
    
    
        FirstBeanDefinitionRegistryPostProcessor firstBeanDefinitionRegistryPostProcessor = new FirstBeanDefinitionRegistryPostProcessor();
        // 将自定义的firstBeanDefinitionRegistryPostProcessor添加到应用上下文中
        applicationContext.addBeanFactoryPostProcessor(firstBeanDefinitionRegistryPostProcessor);
        // ...自定义操作
        System.out.println("SpringApplicationContextInitializer#initialize");
    }
}

2.将 SpringApplicationContextInitializer 作为初始化参数 contextInitializerClasses 配置到 web.xml 中。

<context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>
        com.joonwhee.open.demo.spring.SpringApplicationContextInitializer
    </param-value>
</context-param>

这样,在启动应用时,FirstBeanDefinitionRegistryPostProcessor 就会被添加到 this.beanFactoryPostProcessors集合 中。

1.2 代码块2:PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()

总体流程图:
在这里插入图片描述

public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
    

        // 定义已经处理完成的Bean的集合,当后处理完成后,加入该集合里面
        Set<String> processedBeans = new HashSet<>();

        //[1]beanFactory是DefaultListableBeanFactory,是BeanDefinitionRegistry的实现类,所以肯定满足if
        if (beanFactory instanceof BeanDefinitionRegistry) {
    
    
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            //regularPostProcessors 专门用来存放扩展父接口BeanFactoryPostProcessor的实现类(但是与其子类BeanDefinitionRegistryPostProcessor区分开)
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();

            //registryProcessors 专门用来存放子类BeanDefinitionRegistryPostProcessor
            //子类BeanDefinitionRegistryPostProcessor也扩展了BeanFactoryPostProcessor
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            // 可以先跳过:
            // 循环传进来的beanFactoryPostProcessors,正常情况下,beanFactoryPostProcessors肯定没有数据
            // 因为beanFactoryPostProcessors是获得手动添加的,而不是spring扫描的
            // 只有手动调用annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX)才会有数据
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    
    
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
    
    
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    //如过是BeanDefinitionRegistryPostProcessor的话,调用其方法
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    //添加到BeanDefinitionRegistryPostProcessor集合
                    registryProcessors.add(registryProcessor);
                }
                else {
    
    
                    //添加到普通的集合,非BeanDefinitionRegistryPostProcessor实现的子类
                    regularPostProcessors.add(postProcessor);
                }
            }

            //一个临时变量,用来装载子类BeanDefinitionRegistryPostProcessor
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // 3.调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
            // 3.1 先找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            // 3.2 遍历postProcessorNames,进行过滤
            for (String ppName : postProcessorNames) {
    
    
                 // 3.3 校验是否实现了PriorityOrdered接口
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    
    
                    // 3.4 获取ppName对应的bean实例, 添加到currentRegistryProcessors中
                    //其实就是内置的bean的名称org.springframework.context.annotation.internalConfigurationAnnotationProcessor
                    // beanFactory.getBean(): 这边getBean方法会触发创建ppName对应的bean对象, 目前暂不深入解析
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    //3.5 将要被执行的加入processedBeans,避免后续重复执行
                    processedBeans.add(ppName);
                }
            }
            // 3.6 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            //3.7 合并Processors,为什么要合并,因为registryProcessors是装载BeanDefinitionRegistryPostProcessor的
            //一开始的时候,spring只会执行子类BeanDefinitionRegistryPostProcessor独有的方法
            //而不会执行BeanDefinitionRegistryPostProcessor父类的方法,即BeanFactoryProcessor的方法
            //所以这里需要把处理器放入一个集合中,后续统一执行父类的方法
            registryProcessors.addAll(currentRegistryProcessors);
            
            //3.8 遍历currentRegistryProcessors, 执行子类BeanDefinitionRegistryPostProcessor独有的方法postProcessBeanDefinitionRegistry()方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            
            // 3.9 执行完毕后,清空临时变量
            currentRegistryProcessors.clear();

            // 4.调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类(过程跟上面的步骤3基本一样)
            // 4.1 先找出所有实现BeanDefinitionRegistryPostProcessor接口的类, 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor,
            // 可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
    
    
                //校验是否实现了Ordered接口,与步骤3相比,有个细微区别,就是!processedBeans.contains(ppName)避免重复步骤3已经处理过的
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
    
    
                    //也是实例化bean
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            // 4.2 遍历currentRegistryProcessors,此时是执行我们自定义的子类BeanDefinitionRegistryPostProcessor的特有方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            //清空临时变量
            currentRegistryProcessors.clear();

            //5.最后, 调用所有剩下的子类BeanDefinitionRegistryPostProcessors
            //子类中那些没有同时实现PriorityOrdered接口(步骤3处理的)、或Orderer接口(步骤4处理的)的,
            boolean reiterate = true;
            while (reiterate) {
    
    
                reiterate = false;
                // 5.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的类
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
    
    
                    // 5.2 注意:避免处理已经处理过的
                    if (!processedBeans.contains(ppName)) {
    
    
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                         // 5.3 如果有BeanDefinitionRegistryPostProcessor被执行, 则有可能会产生新的BeanDefinitionRegistryPostProcessor,
                         // 因此这边将reiterate赋值为true, 代表需要再循环查找一次
                        reiterate = true;
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
            }

            //6.上面的代码是执行子类独有的方法,这里需要再把父类BeanFactoryPostProcessor的方法也执行一次
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            //7. 最后, 调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
            //一般情况下,是不会有数据的
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
    
    
            // Invoke factory processors registered with the context instance.
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }
        //------------------------ 
        //到这里 , 入参beanFactoryPostProcessors和容器中的所有子类BeanDefinitionRegistryPostProcessor已经全部处理完毕,
        // 下面开始处理容器中的所有BeanFactoryPostProcessor

         // [8].找出所有实现BeanFactoryPostProcessor接口的类
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

         // 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        // 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
        List<String> orderedPostProcessorNames = new ArrayList<>();
        // 用于存放普通BeanFactoryPostProcessor的beanName(除去实现了PriorityOrdered接口和实现了Ordered接口之后剩下的)
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        
        // 8.1 遍历postProcessorNames, 将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
        for (String ppName : postProcessorNames) {
    
    
            if (processedBeans.contains(ppName)) {
    
    
                // 8.2 跳过已经执行过的
            }
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    
    
                // 8.3 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor,
                // 注意与8.4的区别,这里存储的是实例化后的bean
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
    
    
                // 8.4 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
                // 注意与8.3区别,这里存储的是尚未实例化的beanName
                orderedPostProcessorNames.add(ppName);
            }
            else {
    
    
                // 8.5 添加剩下的普通BeanFactoryPostProcessor的beanName
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // 9.调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor
        // 9.1 对priorityOrderedPostProcessors排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        // 9.2 遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // 10.调用所有实现Ordered接口的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        
        for (String postProcessorName : orderedPostProcessorNames) {
    
    
            // 10.1 获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
         // 10.2 对orderedPostProcessors排序
        sortPostProcessors(orderedPostProcessors, beanFactory);
        // 10.3 遍历orderedPostProcessors, 执行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // 11.调用所有剩下的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        for (String postProcessorName : nonOrderedPostProcessorNames) {
    
    
            // 11.1 获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
         // 11.2 遍历nonOrderedPostProcessors, 执行postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        // 12.清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
        // 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符...
        beanFactory.clearMetadataCache();
    }

1.2.1 注释[1]

判断 beanFactory 是否为 BeanDefinitionRegistry。beanFactory 是在之前的 obtainFreshBeanFactory 方法构建的,具体代码在:AbstractRefreshableApplicationContext.refreshBeanFactory() 方法,代码如下。

@Override
protected final void refreshBeanFactory() throws BeansException {
    
    
    if (hasBeanFactory()) {
    
    
        destroyBeans();
        closeBeanFactory();
    }
    try {
    
    
        // 创建一个新的BeanFactory
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
    
    
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
    
    
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

可以看出,我们构建的 beanFactory 是一个 DefaultListableBeanFactory ,而 DefaultListableBeanFactory 实现了BeanDefinitionRegistry 接口,因此 beanFactory instanceof BeanDefinitionRegistry 结果为 true。

1.2.2 注释[3]

调用如下方法,查找已经注册过的BeanDefinitionRegistryPostProcessor类型的bean:

 beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

这个bean是在哪注册的?
其实是提前注册的!

参见《spring源码》中<1.1.1.2 实例化建BeanDefinition读取器: AnnotatedBeanDefinitionReader>章节提到的知识,利用AnnotatedBeanDefinitionReader注册的内置的几个bean,其中的bean的名称org.springframework.context.annotation.internalConfigurationAnnotationProcessor,class="ConfigurationClassPostProcessor",这个类是BeanDefinitionRegistryPostProcessor的子类

1.2.2.1 注释[3.4]

获取 ppName 对应的 bean 实例,添加到 currentRegistryProcessors 中,准备执行。beanFactory.getBean() 方法会触发创建 ppName 对应的 bean 实例对象,创建 bean 实例是 IoC 的另一个核心内容,之后会单独解析,目前暂不深入解析。

1.2.2.2 注释[3.8]

遍历currentRegistryProcessors, 执行子类BeanDefinitionRegistryPostProcessor独有的方法postProcessBeanDefinitionRegistry()方法,这里实际是执行孙子类ConfigurationClassPostProcessor

究竟做了啥?这个类负责解析JavaConfig类,根据“@ComponentScan(basePackages = {"com.test.spring"})”定义的路径,扫描该路径下的所有带@Component @service等标签的类,并将它们的BeanDefinition全部注册。

我们看下console日志:
在这里插入图片描述
日志显示,我们定义的bean,包括car,MyBeanFactoryPostProcessor,MyBeanPostProcessor均被扫描注册了。

1.2.3 注释[6]

进行排序,该方法在下面也被调用了好几次,见代码块3详解。

1.2.4 注释[8]

自定义的myBeanFactoryPostProcessor终于被注册了
在这里插入图片描述

1.3 代码块3:sortPostProcessors()

private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
    
    
    Comparator<Object> comparatorToUse = null;
    if (beanFactory instanceof DefaultListableBeanFactory) {
    
    
        // 1.获取设置的比较器
        comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
    }
    if (comparatorToUse == null) {
    
    
        // 2.如果没有设置比较器, 则使用默认的OrderComparator
        comparatorToUse = OrderComparator.INSTANCE;
    }
    // 3.使用比较器对postProcessors进行排序
    Collections.sort(postProcessors, comparatorToUse);
}

默认情况下,比较器为 OrderComparator;如果配置了 annotation-config,并且值为true,使用的是 AnnotationAwareOrderComparator(《Spring IoC:context:component-scan节点解析》 代码块17中设置了dependencyComparator 属性为 AnnotationAwareOrderComparator.INSTANCE),AnnotationAwareOrderComparator 继承自 OrderComparator,只是重写了部分方法,比较器的部分代码如下:

@Override
public int compare(Object o1, Object o2) {
    
    
    return doCompare(o1, o2, null);
}
 
private int doCompare(Object o1, Object o2, OrderSourceProvider sourceProvider) {
    
    
    // 判断o1是否实现了PriorityOrdered接口
    boolean p1 = (o1 instanceof PriorityOrdered);
    // 判断o2是否实现了PriorityOrdered接口
    boolean p2 = (o2 instanceof PriorityOrdered);
    // 1.如果o1实现了PriorityOrdered接口, 而o2没有, 则o1排前面
    if (p1 && !p2) {
    
    
        return -1;
    }
    // 2.如果o2实现了PriorityOrdered接口, 而o1没有, 则o2排前面
    else if (p2 && !p1) {
    
    
        return 1;
    }
 
    // 3.如果o1和o2都实现(都没实现)PriorityOrdered接口
    // Direct evaluation instead of Integer.compareTo to avoid unnecessary object creation.
    // 拿到o1的order值, 如果没实现Ordered接口, 值为Ordered.LOWEST_PRECEDENCE
    int i1 = getOrder(o1, sourceProvider);
    // 拿到o2的order值, 如果没实现Ordered接口, 值为Ordered.LOWEST_PRECEDENCE
    int i2 = getOrder(o2, sourceProvider);
    // 4.通过order值(order值越小, 优先级越高)排序
    return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
}

比较器的逻辑很简单,实现 PriorityOrdered 接口的优先级最高,如果两个对象都实现(都没实现)PriorityOrdered 接口,则根据 order 值(实现 Ordered 接口时,需要实现 getOrder() 方法,返回 order 值)来进行比较,order 值越小,优先级越高。

3. 扩展知识

3.1 BeanDefinitionRegistryPostProcessor 的扩展使用

使用方法比较简单,新建一个类实现 BeanDefinitionRegistryPostProcessor 接口,并将该类注册到 Spring IoC 容器中。

package com.joonwhee.open.demo.spring;
 
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
 
/**
 * @author joonwhee
 * @date 2019/2/18
 */
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, Ordered {
    
    
 
    //BeanDefinitionRegistryPostProcessor接口定义的抽象方法
    //一般用来完成bean的注册功能
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    
    
        System.out.println("MyBeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry");
        // 自己的逻辑处理
    }
    
    //爷爷接口,BeanFactoryPostProcessor定义的
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("MyBeanDefinitionRegistryPostProcessor#postProcessBeanFactory");
        // 自己的逻辑处理
    }
 
    @Override
    public int getOrder() {
    
    
        return 0;
    }
}

具体的使用场景,需要读者自己去探讨,这边给一个常见的使用例子。

例子:

我们通常在使用 Mybatis + Spring 时,经常用到的 org.mybatis.spring.mapper.MapperScannerConfigurer 就是一个BeanDefinitionRegistryPostProcessor。MapperScannerConfigurer 在 postProcessBeanDefinitionRegistry() 方法中进行了一些操作,主要是:
扫描 basePackage 指定的目录,将该目录下的类(通常是 DAO/MAPPER 接口)封装成 BeanDefinition 并加载到 BeanFactory 中。

因此,我们可以看到我们项目中的 DAO(MAPPER)接口,通常都没有使用注解或 XML 的方式注册到 Spring 容器,但是我们还是可以在 Service 服务中,使用 @Autowire 注解来将其注入到 Service 中,就是因为这个原因。

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!--basePackage指定要扫描的包,在此包之下的映射器都会被搜索到。可指定多个包,包与包之间用逗号或分号分隔-->
    <property name="basePackage" value="com.joonwhee.open.demo.mapper"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

MapperScannerConfigurer.java:
在这里插入图片描述

3.2. BeanFactoryPostProcessor 接口的扩展使用

使用方法跟 BeanDefinitionRegistryPostProcessor 类似,且是BeanDefinitionRegistryPostProcessor的父接口,执行优先级低一些。

package com.joonwhee.open.demo.spring;
 
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
 
/**
 * @author joonwhee
 * @date 2019/2/18
 */
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("MyBeanFactoryPostProcessor#postProcessBeanFactory");
        // 自己的逻辑处理
    }
}

4. 总结

invokeBeanFactoryPostProcessors 方法的内容其实比较少,大部分过程在代码块2的注释都已经写清楚,这边在稍微总结一下。

1.整个 invokeBeanFactoryPostProcessors 方法围绕两个接口,BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor,其中 BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor 。BeanDefinitionRegistryPostProcessor 主要用来在常规 BeanFactoryPostProcessor 检测开始之前注册其他 Bean 定义,说的简单点,就是 BeanDefinitionRegistryPostProcessor 具有更高的优先级,执行顺序在 BeanFactoryPostProcessor 之前。

2.整个 invokeBeanFactoryPostProcessors 方法操作了 3 种 bean 对象:

  • 入参 beanFactoryPostProcessors:这个我们在代码块1中解析过,拿的是 AbstractApplicationContext 类的 beanFactoryPostProcessors 属性值,也就是在之前已经添加到 beanFactoryPostProcessors 中的 BeanFactoryPostProcessor。

    一般情况下为空,除非手动(额外配置)添加进去

  • BeanDefinitionRegistryPostProcessor 接口实现类:实现了 BeanDefinitionRegistryPostProcessor 接口,并且注册到 Spring IoC容器中。

  • 常规 BeanFactoryPostProcessor 接口实现类:实现了 BeanFactoryPostProcessor 接口,并且注册到 Spring IoC容器中。

3.操作3种 bean 对象具体指的是调用它们重写的方法,调用实现方法时会遵循以下的优先级:

  • 第一优先级:入参 beanFactoryPostProcessors 中的 BeanDefinitionRegistryPostProcessor, 调用 postProcessBeanDefinitionRegistry 方法(2.1.1)。
  • 第二优先级:BeanDefinitionRegistryPostProcessor 接口实现类,并且实现了 PriorityOrdered 接口,调用 postProcessBeanDefinitionRegistry 方法(3.8)。
  • 第三优先级:BeanDefinitionRegistryPostProcessor 接口实现类,并且实现了 Ordered 接口,调用 postProcessBeanDefinitionRegistry 方法(4.2)。
  • 第四优先级:除去第二优先级和第三优先级,剩余的 BeanDefinitionRegistryPostProcessor 接口实现类,调用 postProcessBeanDefinitionRegistry 方法(5.4)。
  • 第五优先级:所有 BeanDefinitionRegistryPostProcessor 接口实现类,调用 postProcessBeanFactory 方法(6)。
  • 第六优先级:入参 beanFactoryPostProcessors 中的常规 BeanFactoryPostProcessor,调用 postProcessBeanFactory 方法(7)。
  • 第七优先级:常规 BeanFactoryPostProcessor 接口实现类,并且实现了 PriorityOrdered 接口,调用 postProcessBeanFactory 方法(9.2)。
  • 第八优先级:常规 BeanFactoryPostProcessor 接口实现类,并且实现了 Ordered 接口,调用 postProcessBeanFactory 方法(10.3)。
  • 第九优先级:除去第七优先级和第八优先级,剩余的常规 BeanFactoryPostProcessor 接口的实现类,调用 postProcessBeanFactory 方法(11.2)。

4.本文还引入了两个用于排序的重要接口:PriorityOrdered 和 Ordered,其中 PriorityOrdered 继承了 Ordered,并且 PriorityOrdered 的优先级要高于 Ordered,这跟 BeanDefinitionRegistryPostProcessor 继承 BeanFactoryPostProcessor 有点类似。实现 Ordered 接口需要重写 getOrder 方法,返回一个用于排序的 order 值,order 值的范围为 Integer.MIN_VALUE ~ Integer.MAX_VALUE,order 值越小优先级越高,Integer.MIN_VALUE 拥有最高优先级,而 Integer.MAX_VALUE 则对应的拥有最低优先级。

5.常见的 Java EE 相关的框架或者中间件,经常使用 BeanFactoryPostProcessor 来进行扩展,例如上面的 Mybatis,因此了解 BeanFactoryPostProcessor 的原理会对之后理解其他中间件的原理有帮助。


参考:
《Spring IoC源码学习:invokeBeanFactoryPostProcessors 详解》

猜你喜欢

转载自blog.csdn.net/m0_45406092/article/details/114847361