Spring Ioc源码分析系列–Ioc容器BeanFactoryPostProcessor后置处理器分析

Spring Ioc源码分析系列–Ioc容器BeanFactoryPostProcessor后置处理器分析

前言

上一篇文章Spring Ioc源码分析系列–Ioc源码入口分析已经介绍到Ioc容器的入口 refresh()方法,并且分析了 refresh()方法里面的前三个子方法分析了一下。还记得分析了什么麽?估计早忘了分析了什么,可以说是看了个寂寞。但是不要慌,看了忘肯定是正常的,需要回顾复习一下,最好做点笔记记录一下,有自己的沉淀才会印象深刻。最好跟着代码自己调试几遍, 纸上得来终觉浅,绝知此事要躬行

好了,这里回顾一下上篇文章的内容。上篇文章主要分析了三个方法, prepareRefresh()进行了一些容器启动前的属性设置, obtainFreshBeanFactory()方法完成了读取配置文件,该方法的实现会针对xml配置创建内部容器,该容器负责bean的创建与管理,会进行 BeanDefinition的注册, prepareBeanFactory(beanFactory)方法主要注册一些容器中需要使用的系统 bean,例如 classloaderBeanFactoryPostProcessor等。

喝了鸡汤看了回顾,接下来才是今天这篇文章的正文开始。

思考一个问题, Spring提供了非常良好的扩展性,那么扩展性在哪里体现?这个问题仁者见仁智者见智,但是把场景压缩一下,压缩到上一篇文章我们已经获得了一个加载完成 BeanDefinition的容器上,我在统一的 BeanDefinition加载完成后,我想修改某一个或者增加某一个 BeanDefinition这时候怎么实现呢?

对Spring熟悉点的读者可能已经猜到,这时候就可以使用 BeanFactoryPostProcessor后置处理器来完成这个操作了,那么这篇文章会解决两个疑问:

  • BeanFactoryPostProcessor是什么以及如何使用?
  • BeanFactoryPostProcessor在源码里的调用逻辑?

第一个疑问会通过一个例子来说明,第二个疑问会通过源码分析来阐述。废话少说,先进行 BeanFactoryPostProcessor介绍,然后还是使用上一篇文章的例子来实现用 BeanFactoryPostProcessor来替换 UserService的实现。

BeanFactoryPostProcessor介绍

这是一个容器的钩子方法,允许自定义修改应用程序上下文的 bean 定义,调整上下文底层 bean 工厂的 bean 属性值。对于针对用系统管理员的自定义配置文件覆盖应用程序上下文中配置的 bean 属性非常有效。 BeanFactoryPostProcessor可以与 bean 定义交互和修改,但不能与 bean 实例交互。这样做可能会导致过早的 bean 实例化,违反容器并导致意外的副作用。如果需要 bean 实例交互,请考虑改为实现 BeanPostProcessorApplicationContext 自动检测其 bean 定义中的 BeanFactoryPostProcessor ,并在创建任何其他 bean 之前应用它们。 BeanFactoryPostProcessor 也可以通过编程方式注册到 ConfigurableApplicationContext

这个类只有一个方法,入参为当前容器,下面来看一下 postProcessBeanFactory()这个方法。

@FunctionalInterface
public interface BeanFactoryPostProcessor {

    /**
     * Modify the application context's internal bean factory after its standard
     * initialization. All bean definitions will have been loaded, but no beans
     * will have been instantiated yet. This allows for overriding or adding
     * properties even to eager-initializing beans.
     *
     * 在标准初始化之后修改应用程序上下文的内部 bean 工厂。
     * 所有 bean 定义都将被加载,但还没有 bean 被实例化。
     * 这允许覆盖或添加属性,甚至是急切初始化的 bean。
     *
     * @param beanFactory the bean factory used by the application context
     * @throws org.springframework.beans.BeansException in case of errors
     */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

可以看到这里的操作空间是非常大的,直接把当前的容器传入, 意味着你可以在当前容器的基础上做任何操作。就比如你天天看着女神,可望而不可即,但是某天通过一个传送门,把女神送到了你家里,你是不是可以为所欲为了,想干什么就干什么,例如你可以让她穿你喜欢的衣服,吃你喜欢吃的东西等等。

代码例子

那下面就用代码实现一下。还是在上一篇文章Spring Ioc源码分析系列–Ioc源码入口分析的基础上进行添加代码, 所有源码都可以在我的仓库ioc-sourcecode-analysis-code-demo里找到 。

首先新建一个 ReplaceUserServiceImpl类实现 UserService

/**
 * @author Codegitz
 * @date 2022/5/12 15:57
 **/
public class ReplaceUserServiceImpl implements UserService {
    @Override
    public User getUser(String name, String age) {
        User user = new User();
        user.setId("1");
        // 这里更改了赋值
        user.setName("ReplaceUser-" + name);
        user.setAge(age);
        return user;
    }
}

接着用一个类实现 BeanFactoryPostProcessor。可以看到我这里的逻辑也非常简单,就是判断是否存在一个名为 userServiceBeanDefinition,如果有则把它的实现替换为 io.codegitz.service.impl.ReplaceUserServiceImpl

/**
 * @author Codegitz
 * @date 2022/5/12 16:01
 **/
public class ReplaceUserBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        if (beanFactory.containsBeanDefinition("userService")){
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
            beanDefinition.setBeanClassName("io.codegitz.service.impl.ReplaceUserServiceImpl");
        }
    }
}

后置处理器已经准备好,接下来把后置处理器注册到容器里,我代码例子采用的是 xml方式。


到这里一切都完成了,那么就可以启动引导类跑一下看看效果了。可以看到这里的实现已经替换为 ReplaceUserServiceImpl,说明我们的 ReplaceUserBeanFactoryPostProcessor后置处理器是生效了,那么是怎么生效的呢?进入下一节的源码分析。

Spring Ioc源码分析系列--Ioc容器BeanFactoryPostProcessor后置处理器分析

源码分析

上面已经通过一个例子实现了功能,那么这个源码里是怎么实现的呢?这里会衔接上一篇文章的源码分析,继续在 refresh()方法里游荡。上一篇已经分析了前三个,这篇会继续往下分析两个方法,分别是 postProcessBeanFactory(beanFactory)invokeBeanFactoryPostProcessors(beanFactory)invokeBeanFactoryPostProcessors(beanFactory)就是后置处理器的逻辑,衔接了上文的例子。好家伙,互相衔接。

postProcessBeanFactory(beanFactory)

这是一个空方法,留给子类实现,主要是一些 web相关的 ApplicationContext会重写这个方法,传入的是当前容器,操作空间也是非常大的。由于是个空方法,这里不再赘述。

    /**
     * Modify the application context's internal bean factory after its standard
     * initialization. All bean definitions will have been loaded, but no beans
     * will have been instantiated yet. This allows for registering special
     * BeanPostProcessors etc in certain ApplicationContext implementations.
     *
     * 在标准初始化之后修改应用程序上下文的内部 bean 工厂。
     * 所有 bean 定义都已经被加载,但还没有 bean 被实例化。
     * 这允许在某些 ApplicationContext 实现中注册特殊的 BeanPostProcessors 等。
     *
     * @param beanFactory the bean factory used by the application context
     */
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    }

invokeBeanFactoryPostProcessors(beanFactory)

接下来就进入了今天的重头戏,跟进代码,可以看到主要的代码实现委托给了 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())去实现。

    /**
     * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
     * respecting explicit order if given.
     * Must be called before singleton instantiation.
     *
     * 实例化并调用所有已注册的 BeanFactoryPostProcessor bean,如果给定顺序,则按照顺序去执行
     * 所有的后置处理器必须在其他的单例bean实例化之前被调用
     */
    //实例化并且调用所有BeanFactoryPostProcessor beans
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 这个方法会进行两种操作
        // 1.把给定的 BeanFactoryPostProcessor 传入执行
        // 2.自动扫描容器里的所有的 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)
        // 检测是否有用于类型匹配的临时 ClassLoader 和 LoadTimeWeaver
        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())里面的代码。这个方法比较长,但是逻辑却非常简单,跟着注释看一下理解起来问题不大。

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

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

        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 常规的BeanFactoryPostProcessor后置处理器
            List regularPostProcessors = new ArrayList<>();
            // 扩展注册BeanDefinition的BeanDefinitionRegistryPostProcessor后置处理器
            List 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);
                }
            }

            // 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.
            // 这里不会初始化FactoryBeans,因为先初始化了的话BeanFactoryPostProcessor就无法对已经初始化的bean生效了
            List currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // 首先会调用实现了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();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            // 接下来调用实现了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();

            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            // 最后,调用没有实现上述接口的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?
                        // 因为这里BeanDefinitionRegistryPostProcessor可能会注册另外的BeanFactoryPostProcessor,
                        // 所以需要循环去迭代,直到当前容器里没有BeanFactoryPostProcessor为止
                        reiterate = true;
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                // 这里可能会继续注册BeanFactoryPostProcessor
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
            }

            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            // 前面已经处理完成了所有的 BeanDefinitionRegistryPostProcessor,
            // 接下来这两个方法就是处理 BeanFactoryPostProcessor,
            // 注意这里只是处理了方法传入的 beanFactoryPostProcessors ,
            // 处理完这个后后续的逻辑还是会自动检测当前容器里所有的BeanFactoryPostProcessor,然后分类逐次调用
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            // Invoke factory processors registered with the context instance.
            // 如果给定的beanFactory不是BeanDefinitionRegistry,
            // 那么就不需要进行前面调用 BeanDefinitionRegistryPostProcessor 的操作,
            // 直接调用给定的 beanFactoryPostProcessors
            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!
        // 这里的逻辑跟上面的 BeanDefinitionRegistryPostProcessor 处理逻辑类似
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        // 按照不同的优先级去分类 BeanFactoryPostProcessor
        List priorityOrderedPostProcessors = new ArrayList<>();
        List orderedPostProcessorNames = new ArrayList<>();
        List 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.
        // 首先调用实现了 PriorityOrdered 接口的 BeanFactoryPostProcessor
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        // 其次调用实现了 Ordered 接口的 BeanFactoryPostProcessor
        List orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        // 最后调用没有实现上述接口的 BeanFactoryPostProcessor
        List 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...
        // 清除缓存的 merged bean definitions 定义,因为后处理器可能已经修改了原始元数据,例如替换值中的占位符...
        beanFactory.clearMetadataCache();
    }

这个方法主要做了以下几件事:

  • 首先会判断当前容器的类型是不是 BeanDefinitionRegistry类型,如果是,则判断 给定的 beanFactoryPostProcessors是否存在 BeanDefinitionRegistryPostProcessor类型的后置处理器,如果有则执行 postProcessBeanDefinitionRegistry()方法,进行 BeanDefinition的注册。接着会分别获取当前容器里实现了 PriorityOrderedOrdered接口和没有实现排序接口的 BeanDefinitionRegistryPostProcessor,排序后依次执行。
  • 如果不是 BeanDefinitionRegistry类型,则直接调用 invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory)方法调用所有给定的 BeanFactoryPostProcessor
  • 经过前面两步,已经处理完成了给定了 beanFactoryPostProcessors,这里会去检测执行容器里存在的 BeanFactoryPostProcessor。这里也会按照 PriorityOrderedOrdered接口以及没有实现排序接口的顺序去调用。
  • 最后会清空容器里元数据的配置缓存

这个方法的逻辑是比较简单的,就是代码量比较大,需要耐心看完。

接下来看下里面的一些字方法的内容

sortPostProcessors()完成后置处理器排序

    private static void sortPostProcessors(List postProcessors, ConfigurableListableBeanFactory beanFactory) {
        // 比较简单,就是获取一个比较器 Comparator ,至于 Comparator 的原理,可以自己去看下相关文章
        Comparator comparatorToUse = null;
        if (beanFactory instanceof DefaultListableBeanFactory) {
            comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
        }
        if (comparatorToUse == null) {
            comparatorToUse = OrderComparator.INSTANCE;
        }
        // 排序
        postProcessors.sort(comparatorToUse);
    }

invokeBeanDefinitionRegistryPostProcessors()调用所有的BeanDefinitionRegistryPostProcessor

这个方法也比较简单,就是逐个调用一下 BeanDefinitionRegistryPostProcessor后置处理器。

    /**
     * Invoke the given BeanDefinitionRegistryPostProcessor beans.
     * 调用给定的 BeanDefinitionRegistryPostProcessor bean。
     */
    private static void invokeBeanDefinitionRegistryPostProcessors(
            Collection postProcessors, BeanDefinitionRegistry registry) {

        for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
            postProcessor.postProcessBeanDefinitionRegistry(registry);
        }
    }

invokeBeanFactoryPostProcessors()调用所有的BeanFactoryPostProcessor

逐个调用一下 BeanFactoryPostProcessor后置处理器。

    /**
     * Invoke the given BeanFactoryPostProcessor beans.
     * 调用给定的 BeanFactoryPostProcessor bean。
     */
    private static void invokeBeanFactoryPostProcessors(
            Collection postProcessors, ConfigurableListableBeanFactory beanFactory) {

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

beanFactory.getBeanNamesForType()根据类型获取bean名称

beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)会根据传入的类型获取该类型所有的bean名称。

跟进代码查看,会调用 doGetBeanNamesForType()方法进行获取。

    public String[] getBeanNamesForType(@Nullable Class type, boolean includeNonSingletons, boolean allowEagerInit) {
        // 配置没有冻结 || 类型为空 || 不允许提前初始化 则进入
        if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
            return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
        }
        Map, String[]> cache =
                (includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
        String[] resolvedBeanNames = cache.get(type);
        if (resolvedBeanNames != null) {
            return resolvedBeanNames;
        }
        // 允许提前初始化
        resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
        if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
            cache.put(type, resolvedBeanNames);
        }
        return resolvedBeanNames;
    }

跟进 doGetBeanNamesForType()方法,这个方法也比较长,但是逻辑也比较清晰,就是遍历了 beanDefinitionNames判断是否符合类型要求,符合则返回。

    private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
        List result = new ArrayList<>();

        // Check all bean definitions.
        // 从所有的 beanDefinitionNames 检查所有符合类型要求的 bean ,加入 result
        for (String beanName : this.beanDefinitionNames) {
            // Only consider bean as eligible if the bean name
            // is not defined as alias for some other bean.
            // 如果 bean 名称未定义为其他 bean 的别名,则该bean符合要求。
            if (!isAlias(beanName)) {
                try {
                    // 获取 beanName 的 RootBeanDefinition
                    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                    // Only check bean definition if it is complete.
                    if (!mbd.isAbstract() && (allowEagerInit ||
                            (mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
                                    !requiresEagerInitForType(mbd.getFactoryBeanName()))) {
                        boolean isFactoryBean = isFactoryBean(beanName, mbd);
                        BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
                        // 类型是否匹配
                        boolean matchFound = false;
                        boolean allowFactoryBeanInit = allowEagerInit || containsSingleton(beanName);
                        boolean isNonLazyDecorated = dbd != null && !mbd.isLazyInit();
                        // 主要就是调用 isTypeMatch() 方法判断类型是否匹配
                        if (!isFactoryBean) {
                            if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
                                matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                            }
                        }
                        else  {
                            if (includeNonSingletons || isNonLazyDecorated ||
                                    (allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
                                matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                            }
                            if (!matchFound) {
                                // In case of FactoryBean, try to match FactoryBean instance itself next.
                                beanName = FACTORY_BEAN_PREFIX + beanName;
                                matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                            }
                        }
                        // 如果匹配则加入
                        if (matchFound) {
                            result.add(beanName);
                        }
                    }
                }
                catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
                    // 省略部分异常处理..
                }
            }
        }

        // Check manually registered singletons too.
        // 检查手动注册的单例bean
        for (String beanName : this.manualSingletonNames) {
            try {
                // In case of FactoryBean, match object created by FactoryBean.
                if (isFactoryBean(beanName)) {
                    if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
                        result.add(beanName);
                        // Match found for this bean: do not match FactoryBean itself anymore.
                        continue;
                    }
                    // In case of FactoryBean, try to match FactoryBean itself next.
                    beanName = FACTORY_BEAN_PREFIX + beanName;
                }
                // Match raw bean instance (might be raw FactoryBean).
                // 匹配则加入
                if (isTypeMatch(beanName, type)) {
                    result.add(beanName);
                }
            }
            catch (NoSuchBeanDefinitionException ex) {
                // 省略部分异常...
            }
        }

        return StringUtils.toStringArray(result);
    }

到这里 BeanFactoryPostProcessor的源码调用以及相关的逻辑分析完了,是不是比较简单。

小结

这篇文章主要是介绍了 BeanFactoryPostProcessor后置处理器的使用和底层原理。文章开头首先回顾了上一篇文章的内容,然后例子驱动分析,先用简单的例子实现了 BeanFactoryPostProcessor的使用,然后再进行了源码分析,整个文章下来思路是比较清晰的。那么看到这里,有没有解决了文章开头的两个疑问?

  • BeanFactoryPostProcessor是什么以及如何使用?
  • BeanFactoryPostProcessor在源码里的调用逻辑?

如果没有,那不怪你,可能是我写得不好。

今天是汶川地震14周年,生命无常,向遇难的同胞寄托哀思,向参与救援的同胞致敬。

如果有人看到这里,那在这里老话重提。 与君共勉,路漫漫其修远兮,吾将上下而求索。

Original: https://www.cnblogs.com/codegitz/p/16263623.html
Author: Codegitz
Title: Spring Ioc源码分析系列–Ioc容器BeanFactoryPostProcessor后置处理器分析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/714247/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • MySQL 知识点总结(简易版)

    MySQL 总结(简易版) 基本语法 0. 1基本语法 &#x767B;&#x5F55;MySQL $ mysql -u root -p12345612 &…

    技术杂谈 2023年7月11日
    065
  • C#和Excel进行报表开发

    2年不C#开发了,把一些压箱底的资料,全部整理了下,该公开放博客就放博客了。 这个是C# 操作Excel的资料,内容截图如下。可以点击此处下载(C_SHARP_FOR_EXCEL_…

    技术杂谈 2023年5月30日
    0103
  • django系列

    博客园: https://www.cnblogs.com/wupeiqi/articles/5246483.html 全教程: http://c.biancheng.net/dja…

    技术杂谈 2023年7月24日
    071
  • Javaweb学习-HTML

    ; ; 重新开始HTML,之前学的都忘了 posted @2022-03-24 21:27 HelloHui 阅读(7 ) 评论() 编辑 Original: https://ww…

    技术杂谈 2023年6月21日
    089
  • 阿里云一面:并发场景下的底层细节-伪共享问题

    最近看书看到的伪共享问题,直接触碰到知识盲区了,之前确实没听说过这个东西,打开百度就像吃饭一样自然。 虽然面经上出现的次数不多,不过我觉得还是很重要的一个问题,而且不难,花个五分钟…

    技术杂谈 2023年7月25日
    066
  • 京东联盟开发(13)——获取官方活动推广数据

    数据如下,标准的json数据,转成数组遍历获取即可 { "code":200, "message":"success",…

    技术杂谈 2023年5月31日
    0116
  • 三层架构与MVC &amp; 设计模式的较量

    刚刚学习了三层架构,并且正在实际应用中,但随着学习的深入,又了解到了一个叫MVC 的东西,(早在设计模式中就听到过MVC,仅仅是简单查了一下什么意思.)如今正好把这三个东西放在一起…

    技术杂谈 2023年5月31日
    069
  • 如何为visio扩展云服务图标

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    技术杂谈 2023年7月25日
    071
  • Java基础语法(真随笔,不完整)

    ; ; 一、注释 (1)单行注释 // (2)多行注释 / / (3)文档注释 JavaDoc /* /(用来生成自己的API文档) 二、标识符 (1)都以A-Z、a-z、$、_ …

    技术杂谈 2023年6月21日
    096
  • HTTP协议

    请求报头允许客户端向服务器端传递请求的附加信息以及客户端自身的信息。 Accept Accept请求报头域用于指定客户端接受哪些类型的信息。eg:Accept:image/gif …

    技术杂谈 2023年7月24日
    081
  • Python数据分析–Numpy常用函数介绍(6)–Numpy中与股票成交量有关的计算

    成交量(volume)是投资中一个非常重要的变量,它是指在某一时段内具体的交易数,可以在分时图中绘制,包括日线图、周线图、月线图甚至是5分钟、30分钟、60分钟图中绘制。 股票市场…

    技术杂谈 2023年7月25日
    088
  • Python3中datetime不同时区转换介绍与踩坑

    最近的项目需要根据用户所属时区制定一些特定策略,学习、应用了若干python3的时区转换相关知识,这里整理一部分记录下来。 下面涉及的几个概念及知识点: GMT时间:Greenwi…

    技术杂谈 2023年6月21日
    072
  • 5、Swift协程详解:取消Task

    Task 的取消就是个状态 Task 的取消其实非常简单,就是将 Task 标记为取消状态。那 Task 的执行体要怎么做才能让任务真正取消呢?我们先看个简单的例子: 我们创建了一…

    技术杂谈 2023年6月1日
    073
  • 在jupyter中配置c++内核

    安装 xeus-cling conda install xeus-cling -c conda-forg xeus-cling 是一个用于编译解释于C++的Jupyter内核目前,…

    技术杂谈 2023年7月11日
    0104
  • Go实现安全双检锁的方法和最佳实践

    不安全的双检锁 从其他语言转入Go语言的同学经常会陷入一个思考:如何创建一个单例? 有些同学可能会把其它语言中的双检锁模式移植过来,双检锁模式也称为懒汉模式,首次用到的时候才创建实…

    技术杂谈 2023年7月11日
    0109
  • solr查询score机制

    首先,solr使用的是默认的评分机制,要搞明白lucene默认评分机制,需要首先了解一下lucene的查询对象。 1、termquery 2、boolean query 3、ran…

    技术杂谈 2023年5月31日
    092
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球