Spring源码学习笔记(10)——BeanFactoryPostProcessor

时间:2022-07-24
本文章向大家介绍Spring源码学习笔记(10)——BeanFactoryPostProcessor,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Spring源码学习笔记(10)——BeanFactoryPostProcessor

一. 简介

BeanFactoryPostProcessor支持对IoC容器内部的所有BeanDefinition进行定制化修改, 并且可以根据IoC容器内部的BeanFactory进行Bean属性值的适配。

也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置’order’属性来控制各个BeanFactoryPostProcessor的执行次序。

本节主要介绍一下BeanFactoryPostProcessor的简单使用及其原理。

一. BeanPostProcessor VS BeanFactoryPostProcessor

  • BeanPostProcessor:拦截Bean创建后的初始化操作,在Bean的初始化前/后执行额外的处理。BeanPostProcessor工作时Bean已经创建好了。BeanPostProcessor操作的是Bean实例
  • BeanFactoryPostProcessor:拦截IoC容器内部的BeanFactory的标准初始化操作,其执行时机为所有的BeanDefinition加载完成,并且创建Bean之前。BeanFactoryPostProcessor操作的是BeanDefinition。

注:可以用BeanFactoryPostProcessor修改BeanDefinition,但是千万不要出来Bean的实例化,否则可能导致Bean被过早地实例化出来,污染IoC容器,造成潜在的危险。

二. BeanFactoryPostProcessor使用示例

创建自定义BeanFactoryPostProcessor实例:

public class SimpleBeanFactoryPostProcessor implements BeanFactoryPostProcessor{
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.err.println("BeanDefinitionCount: " + beanFactory.getBeanDefinitionCount());
        System.err.println("BeanDefinitionNames: " + Arrays.asList(beanFactory.getBeanDefinitionNames()));
    }
}

创建配置类,注册SimpleBeanFactoryPostProcessor和自定义Bean:

@Configuration
@ComponentScan
public class MainConfig {
    @Bean
    public SimpleBeanFactoryPostProcessor simpleBeanFactoryPostProcessor(){
        return new SimpleBeanFactoryPostProcessor();
    }

    @Bean
    public Blue blue(){
        return new Blue();
    }
}

加载Ioc容器,可以看到控制台打印,先进行BeanFactoryPostProcessor的处理,再实例化Bean。

BeanDefinitionCount: 19
BeanDefinitionNames: [org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, mainConfig, org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor, org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor, cat, userDao, simpleCalculator, calculatorAspect, applicationContextHolder, userController, userService, blue, simpleBeanFactoryPostProcessor, org.springframework.aop.config.internalAutoProxyCreator]
Construct Blue

三. 源码分析

下面结合源码分析BeanFactoryPostProcessor的工作流程:

首先看BeanFactoryPostProcessor接口,其定义十分简单,只有一个方法,进行BeanFactory初始化后的处理:

public interface BeanFactoryPostProcessor {
    //拦截IoC容器内部的BeanFactory的标准初始化过程,该方法在所有BeanDefinition加载完毕,且Bean实例创建之前调用。
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

BeanFactoryPostProcessor的调用在IoC容器的refresh()方法中:

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        //刷新前的准备
        prepareRefresh();

        //刷新IoC容器内部的BeanFactory,并加载BeanDefinition
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        prepareBeanFactory(beanFactory);

        try {
            postProcessBeanFactory(beanFactory);

            //调用BeanFactoryPostProcessor处理
            invokeBeanFactoryPostProcessors(beanFactory);

            //向容器中注册BeanPostProcessor后处理器
            registerBeanPostProcessors(beanFactory);

            //初始化消息源
            initMessageSource();

            //初始化事件分发器
            initApplicationEventMulticaster();

            onRefresh();

            //初始化事件监听器
            registerListeners();

            //实例化所有非lazy的单实例Bean
            finishBeanFactoryInitialization(beanFactory);

            //刷新完成
            finishRefresh();
        }
    }
}

调用BeanFactoryPostProcessor的处理在invokeBeanFactoryPostProcessors()方法中。可以看到该方法在obtainFreshBeanFactory()加载BeanDefinition后,在finishBeanFactoryInitialization()实例化Bean之前。

调用BeanFactoryPostProcessor的核心逻辑在PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法中:

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

    //如果存在BeanDefinitionRegistryPostProcessor,则首先调用如果存在BeanDefinitionRegistryPostProcessor处理
    Set<String> processedBeans = new HashSet<String>();

    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
        List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
            new LinkedList<BeanDefinitionRegistryPostProcessor>();

        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryPostProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                registryPostProcessors.add(registryPostProcessor);
            }
            else {
                regularPostProcessors.add(postProcessor);
            }
        }

        String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

        List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
        registryPostProcessors.addAll(priorityOrderedPostProcessors);
        invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);

        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
        for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(beanFactory, orderedPostProcessors);
        registryPostProcessors.addAll(orderedPostProcessors);
        invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);

        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName)) {
                    BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
                    registryPostProcessors.add(pp);
                    processedBeans.add(ppName);
                    pp.postProcessBeanDefinitionRegistry(registry);
                    reiterate = true;
                }
            }
        }

        invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    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接口的BeanFactoryPostProcessor
    sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    //然后,调用实现了Ordered接口的BeanFactoryPostProcessor
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(beanFactory, orderedPostProcessors);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    //最后,调用所有其他的BeanFactoryPostProcessors.
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    beanFactory.clearMetadataCache();
}

可以看到,该方法首先将实现了顺序接口的BeanFactoryPostProcessor进行排序,然后按照顺序依次调用,调用的处理在invokeBeanFactoryPostProcessors()方法中:

private static void invokeBeanFactoryPostProcessors(
    Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

    for (BeanFactoryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanFactory(beanFactory);
    }
}

该方法十分简单,即遍历所有的BeanFactoryPostProcessor实例,依次调用其postProcessBeanFactory()方法。