Spring中BeanFactoryPostProcessor的执行

Spring中的BeanFactoryPostProcessor(被称为bean工厂后置处理器)旨在实例化bean之前,对bean的定义进行修改和扩展。本文不会分析具体的bean工厂后置处理器是怎么执行的,而是怎么被执行到的。


前置工作

在应用上下文的主refresh方法中,会调用invokeBeanFactoryPostProcessors方法来执行BeanFactoryPostProcessor

java
spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 第二个参数默认返回的是空列表
    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)
    // 如果LoadTimeWeaver这个bean存在的话,则会添加LoadTimeWeaverAwareProcessor这个运行时织入的后置处理器
    if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

这里是通过一个后置处理器的代理类来执行的,该类中不仅会调用bean工厂后置处理器,还提供了注册bean后置处理器的方法。

下面是代理类中调用bean工厂后置处理器的实现。

java
spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java
public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {


    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set<String> processedBeans = new HashSet<>();

    /*
     * 只有beanFactory是BeanDefinitionRegistry的子类型,那么才支持beanDefinition的后置处理
     *
     * 对于BeanDefinitionRegistryPostProcessor,是先执行postProcessBeanDefinitionRegistry方法,
     * 再执行postProcessBeanFactory方法。
     */
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); // 普通的BeanFactoryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); // 和beanDefinition有关的BeanDefinitionRegistryPostProcessor

        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { // 对传入进来的beanFactoryPostProcessor分类并加入到上面两个集合中
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                // 这里会执行后置处理逻辑,这里也可以看出来,我们手动设置的BeanDefinitionRegistryPostProcessor是最优先执行的
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            else {
                regularPostProcessors.add(postProcessor);
            }
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        // Separate between BeanDefinitionRegistryPostProcessors that implement
        // PriorityOrdered, Ordered, and the rest.
        /*
         * 先执行实现了PriorityOrdered接口的
         * 再执行实现了Ordered接口的
         * 最后才是剩下的
         */
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

        // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
        // 从容器中获取BeanDefinitionRegistryPostProcessor类型的后置处理器的名称
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 先处理实现了PriorityOrdered接口的
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        /*
         * 对currentRegistryProcessors排序
         */
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);

        // 对排好序的currentRegistryProcessors进行遍历,一个一个地执行每个BeanDefinitionRegistryPostProcessor的后置registry逻辑
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
        currentRegistryProcessors.clear(); // 清空

        // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) { // 再处理实现了Order接口的
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        // 对排好序的currentRegistryProcessors进行遍历,一个一个地执行每个BeanDefinitionRegistryPostProcessor的后置registry逻辑
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
        currentRegistryProcessors.clear(); // 清空

        // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
        /*
         * 最后再处理两个排序接口都没有实现的,但是循环内还是排了顺序,因为有可能加载到了新的需要排序的processor。
         * 以及如果在其他BeanDefinitionRegistryPostProcessor执行期间注册了新的BeanDefinitionRegistryPostProcessor,
         * 那么这里以循环来处理。
         */
        boolean reiterate = true;
        while (reiterate) {
            /*
             * 这里的循环是很有必要的,可以思考为什么?
             * 就是因为某个processor可能导入新的processor,所以要一直循环,直到没有引入新的processor为止。
             * 这有点像树结构的层序遍历。
             *
             * 默认是不进行下次while循环
             */
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                /*
                 * 如果当前postProcessor还没有被处理过,则说明要么是上面的逻辑没处理到的,
                 * 或者是其他的BeanDefinitionRegistryPostProcessor引入了新的该类型后置处理器。
                 */
                if (!processedBeans.contains(ppName)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    // 加载到新的processor,则设置为需要再次循环。
                    reiterate = true;
                }
            }
            // 排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 注册
            registryProcessors.addAll(currentRegistryProcessors);
            /*
             * 对排好序的currentRegistryProcessors进行遍历,一个一个地执行每个BeanDefinitionRegistryPostProcessor的后置registry逻辑。
             * 这里有可能引入新的processor,所以需要上面的while循环。
             */
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
            // 清空当前while循环加载到的processor,
            currentRegistryProcessors.clear();
        }

        // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); // 执行和beanDefinition有关的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory逻辑
        /*
         * 执行普通的BeanFactoryPostProcessor的postProcessBeanFactory逻辑,可见我们手动设置的普通BeanFactoryPostprocessor会被优先执行,
         * 也可以看出来Spring是先执行了BeanDefinitionRegistryPostProcessor再执行的普通BeanFactoryPostProcessor
         */
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
        // Invoke factory processors registered with the context instance.
        // 如果是普通的容器,那么执行我们传入进来的那些后置处理器就可以了
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let the bean factory post-processors apply to them!
    // 获取容器中的普通BeanFactoryPostProcessor,后面也是按照和上面一样的套路(一样的顺序)来执行的
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    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);
        }
    }

    // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 执行普通BeanFactoryPostProcessor的postProcessBeanFactory方法

    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // 执行普通BeanFactoryPostProcessor的postProcessBeanFactory方法

    // Finally, invoke all other BeanFactoryPostProcessors.
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // 执行普通BeanFactoryPostProcessor的postProcessBeanFactory方法

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

虽然这个方法比较长,但是逻辑还是很清晰的。如果bean工厂是BeanDefinitionRegistry接口的子类,那么会先处理BeanDefinitionRegistryPostProcessor这种特殊类型的处理器(下面简称registry处理器)。

  • 先执行参数传入进来的bean工厂后置处理器。
  • 执行被@PriorityOrdered修饰的registry处理器。
  • 再执行被@Ordered修饰的registry处理器。
  • 最后执行没有被上面两个排序注解修饰的registry处理器。

如果bean工厂不是BeanDefinitionRegistry类型的,则只会执行第一步。

不管是在传统的SSM应用中还是在Spring Boot项目中,默认创建的bean工厂是DefaultListableBeanFactory类型的。DefaultListableBeanFactory直接实现了BeanDefinitionRegistry接口,所以是其子类型。

接下来再执行普通的bean工厂后置处理器,先按照实现的排序接口分类,然后按照和上面registry处理器一样的执行顺序来执行。

调用registry处理器

调用registry处理器是在invokeBeanDefinitionRegistryPostProcessors方法中进行的。

java
spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java
private static void invokeBeanDefinitionRegistryPostProcessors(
        Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {

    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
        StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
                .tag("postProcessor", postProcessor::toString);
        postProcessor.postProcessBeanDefinitionRegistry(registry);
        postProcessBeanDefRegistry.end();
    }
}

直接循环调用每个registry处理器的postProcessBeanDefinitionRegistry方法。

调用普通bean工厂后置处理器

java
spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java
private static void invokeBeanFactoryPostProcessors(
        Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

    for (BeanFactoryPostProcessor postProcessor : postProcessors) {
        StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process")
                .tag("postProcessor", postProcessor::toString);
        postProcessor.postProcessBeanFactory(beanFactory);
        postProcessBeanFactory.end();
    }
}

总结

本文分析了bean工厂的后置处理器是怎么被调用到的,以及是怎么对registry处理器进行处理的。这样可以把每个bean工厂后置处理器是怎么执行的和主线连接起来。