Spring源码学习笔记(六)、invokeBeanFactoryPostProcessors

得意时要看淡,失意时要看开。不论得意失意,切莫大意;不论成功失败,切莫止步。志得意满时,需要的是淡然,给自己留一条退路;失意落魄时,需要的是泰然,给自己觅一条出路Spring源码学习笔记(六)、invokeBeanFactoryPostProcessors,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、方法功能概述

// Invoke factory processors registered as beans in the context.
// 调用注册的BeanFactory的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);

调用注册的BeanFactory的后置处理器

二、整体代码展示

//AbstractApplicationContext
/**
 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
 * 实例化并调用所有注册的BeanFactory后置处理器
 * respecting explicit order if given.
 * 如果给定了顺序,按照顺序执行
 * <p>Must be called before singleton instantiation.
 * 单例对象必须在实例化之前调用(因为实例化之后再改动BeanDefinition就没有意义了)
 */
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)
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

点击invokeBeanFactoryPostProcessors进到类PostProcessorRegistrationDelegate中

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

    // 首先调用BeanDefinitionRegistryPostProcessors(如果有)。
    Set<String> processedBeans = new HashSet<>();

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

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

		// 不要在这里初始化FactoryBeans:我们需要保留所有常规bean
		// 未初始化,让bean工厂后处理器应用于它们!
		// 在实现的BeanDefinitionRegistryPostProcessors之间分离
		// PriorityOrdered、Ordered和其他。 
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

        // 首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessors。 
        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);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        // 接下来,调用实现Ordered的BeanDefinitionRegistryPostProcessors。
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            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);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        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);
            currentRegistryProcessors.clear();
        }

        // 现在,调用到目前为止处理的所有处理器的postProcessBeanFactory回调。
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
        // 调用在上下文实例中注册的工厂处理器。
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    // 不要在这里初始化FactoryBeans:我们需要保留所有常规bean
	// 未初始化,让bean工厂后处理器应用于它们!
    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 (String ppName : postProcessorNames) {
        if (processedBeans.contains(ppName)) {
            // 说明上面已经执行了, 下面忽略
        }
        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<>();
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

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

	//清空不必要的元数据信息
    beanFactory.clearMetadataCache();
}

三、invokeBeanFactoryPostProcessors方法第一部分(5-83行)

//这个set的作用是记录执行过的bean名称,防止重复执行
Set<String> processedBeans = new HashSet<>();

if (beanFactory instanceof BeanDefinitionRegistry) {
    //这里看bean工厂是BeanDefinitionRegistry的实例,就执行一系列的复杂操作
    ...
else {
    //如果不是BeanDefinitionRegistry的实例,
    //就直接执行每个Processor的postProcessBeanFactory方法
    invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}

这里我们发现有两个方法被多次调用,invokeBeanDefinitionRegistryPostProcessors和invokeBeanFactoryPostProcessors,这两个方法分别是用来执行实现了BeanDefinitionRegistryPostProcessor接口的bean的postProcessBeanDefinitionRegistry方法和实现了BeanFactoryPostProcessor接口的bean的postProcessBeanFactory方法,postProcessBeanDefinitionRegistry方法是用来对BeanDefinition做一些后置处理的,postProcessBeanFactory是用来对BeanFactory做一些后置处理的。如果bean工厂是BeanDefinitionRegistry的实例,就需要一系列的操作,如果不是BeanDefinitionRegistry的实例,就执行下invokeBeanFactoryPostProcessors方法,下面具体分析下是BeanDefinitionRegistry的实例的情况:

1、(8-22行)其实就是把beanFactoryPostProcessors里的processor按照是不是BeanDefinitionRegistryPostProcessor的实例分开到registryProcessors和regularPostProcessors两个list中,如果是BeanDefinitionRegistryPostProcessor的实例,顺便执行下postProcessBeanDefinitionRegistry方法。(见下图)

BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

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

2、(28-73行)扫描BeanDefinitionRegistryPostProcessor,根据PriorityOrdered、Ordered、其他分成三部分,分别排序后分别触发每个实例的postProcessBeanDefinitionRegistry方法。

3、(76-77行)分别触发registryProcessors和regularPostProcessors两个list中实例的postProcessBeanFactory方法。

三、invokeBeanFactoryPostProcessors方法第二部分(87-126行)

其实第二部分和第一部分差不多,只不过,第二部分是找那些实现了BeanFactoryPostProcessor接口但没有实现BeanDefinitionRegistryPostProcessor接口的实例,也是按照PriorityOrdered、Ordered、其他分成三部分,分别排序后分别触发每个实例的postProcessBeanFactory方法。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/154516.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!