zoukankan      html  css  js  c++  java
  • Spring 源码学习 11:invokeBeanFactoryPostProcessors

    前言

    invokeBeanFactoryPostProcessors 会执行 BeanFactory 的后置处理器。看到这里会有疑问:

    1. 什么是 BeanFactoryPostProcessor ?
    2. BeanfactoryPostProcessor 该如何使用?

    知道了上面两个问题的答案,对 BeanFactoryPostProcessor 有了了解之后,然后再深入源码,继续阅读 invokeBeanFactoryPostProcessors 这个方法。

    作用

    资料还是在官网可以找到答案:

    阅读了一下,大概意思是 Spring IoC 容器允许 BeanFactoryPostProcessor 读取配置元数据,并有可能在容器实例化除 BeanFactoryPostProcessor 实例以外的任何 bean 之前更改它。

    同样可以使用 Ordered 接口对 BeanFactoryPostProcessor 进行排序。

    注意

    BeanFactoryPostProcessor 操作的是 BeanDefinition ,即元数据。但是同样可以通过获取到 BeanFactory 进行实例化 Bean,但是官网很不建议这样使用。

    示例

    使用 BeanFactoryPostProcessor

    @Component
    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
            // 修改 BeanDefinition 信息
            BeanDefinition userComponentBeanDefinition = beanFactory.getBeanDefinition("userComponent");
            userComponentBeanDefinition.setLazyInit(true);
    
            // 修改 Bean 的信息
            // xxx 非常不推荐 beanFactory.getBean 过早的实例化 Bean
            UserComponent bean = beanFactory.getBean(UserComponent.class);
            bean.setUserName("liuzhihang-01");
                
        }
    }
    

    创建自己的 BeanFactoryPostProcessor 并实现 BeanFactoryPostProcessor 接口,添加注解即可。

    当然除了实现 BeanFactoryPostProcessor 接口,还有其他接口可以实现:

    使用 BeanDefinitionRegistryPostProcessor

    BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor,同时扩展了增加了 postProcessBeanDefinitionRegistry 方法。可以支持在 BeanDefinition 注册之后 Bean 实例化之前对 BeanDefinition 进行操作。

    @Component
    public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            // 修改 BeanDefinition 信息
            BeanDefinition userComponentBeanDefinition = beanFactory.getBeanDefinition("userComponent");
            userComponentBeanDefinition.setLazyInit(true);
    
            // 修改 Bean 的信息
            // xxx 非常不推荐 beanFactory.getBean 过早的实例化 Bean
            UserComponent bean = beanFactory.getBean(UserComponent.class);
            bean.setUserName("liuzhihang-01");
        }
    
        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    
            // 注册一个 BeanDefinition
            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(OrderComponent.class);
    
            AbstractBeanDefinition orderComponentBeanDefinition = builder.getBeanDefinition();
    
            registry.registerBeanDefinition("orderComponent", orderComponentBeanDefinition);
    
        }
    }
    

    下面是测试代码截图:

    OrderComponent 类没有添加任何注解,然后注册为 BeanDefinition 之后,从容器中可以获取到 orderComponent。

    如何修改字段属性

    在 Spring 文档上说明,非常不建议在 BeanFactoryPostProcessor 中实例化 Bean,那这时候想修改 Bean 的信息,改如何操作?

    其实可以通过获取到 MutablePropertyValues 后进行操作:

    @Component
    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
            // 修改 BeanDefinition 信息
            BeanDefinition userComponentBeanDefinition = beanFactory.getBeanDefinition("userComponent");
            userComponentBeanDefinition.setLazyInit(true);
    
            MutablePropertyValues userComponentPropertyValues = userComponentBeanDefinition.getPropertyValues();
    
            userComponentPropertyValues.addPropertyValue("userName", "liuzhihang-02");
    
            // 修改 Bean 的信息
            // xxx 非常不推荐 beanFactory.getBean 过早的实例化 Bean
            // UserComponent bean = beanFactory.getBean(UserComponent.class);
            // bean.setUserName("liuzhihang-01");
    
        }
    }
    

    invokeBeanFactoryPostProcessors

    看完前面,我想已经知道了 BeanFactoryPostProcessor 是做什么用的了,而这一步的主要作用就是实例化所有的 BeanFactoryPostProcessor。

    进入源码:

    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 (!IN_NATIVE_IMAGE && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }
    

    其中 getBeanFactoryPostProcessors 方法获取的是自己添加的 BeanFactoryPostProcessor。这句话是什么意思呢?

    public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
        return this.beanFactoryPostProcessors;
    }
    

    看源码,就是直接从 beanFactoryPostProcessors 获取的,那如何向其中添加呢?

    其实调用容器的 addBeanFactoryPostProcessor 方法即可。

    继续阅读重点代码 invokeBeanFactoryPostProcessors

    注意注意,这块代码非常长!

    public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        Set<String> processedBeans = new HashSet<>();
    
        // 判断是否为 BeanDefinitionRegistry
        // debug 发现 这里传入的是 DefaultListableBeanFactory
        // DefaultListableBeanFactory 实现了 BeanDefinitionRegistry
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    
            // 创建了两个 List 集合, 用来存放处理器
            // BeanDefinitionRegistryPostProcessor 是 BeanFactoryPostProcessor 的子接口
            // BeanDefinitionRegistryPostProcessor 还可以额外处理 BeanDefinition, 添加 BeanDefinition
            // 用法可以参考示例
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
            // 循环 beanFactoryPostProcessors
            // beanFactoryPostProcessors 是使用 API context.addBeanFactoryPostProcessor 添加进来的
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    
                // BeanDefinitionRegistryPostProcessor 要单独添加到 registryProcessors
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
    
                    // 处理 Bean 的信息
                    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.
            // 上面循环是执行的我们调用 API 添加的 BeanDefinitionRegistryPostProcessor
            // 下面执行 Spring 自己的 BeanDefinitionRegistryPostProcessor 集合
            // 先执行实现了 PriorityOrdered接口的,然后是 Ordered 接口的,最后执行剩下的
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    
            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // 第一步先调用 BeanDefinitionRegistryPostProcessors 它实现了PriorityOrdered
            // 在初始化 reader 时 在注册了 ConfigurationClassPostProcessor 到容器里面
            // BeanDefinitionRegistryPostProcessor 实现了 BeanDefinitionRegistryPostProcessor
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 添加 bean
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 这里只添加了名字 后面用来判断谁已经执行过了
                    processedBeans.add(ppName);
                }
            }
            // 排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
    
            // 循环执行 processors 的 postProcessBeanDefinitionRegistry 方法
            // 这个得在仔细看
            // debug 看到 执行完这一步我另一个加 @Component 注解的类 注册到 Registry 里面了
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
            // 清除
            currentRegistryProcessors.clear();
    
            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            // 处理实现 Ordered 的 processor
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 只有不包含的才执行, 执行完之后会添加进 processedBeans
                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, beanFactory.getApplicationStartup());
            currentRegistryProcessors.clear();
    
            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            // 最后执行其他
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    // 只有不包含的才执行, 执行完之后会添加进 processedBeans
                    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, beanFactory.getApplicationStartup());
                currentRegistryProcessors.clear();
            }
    
            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            // 上面处理的都是 postProcessBeanDefinitionRegistry 是在 -> BeanDefinitionRegistryPostProcessor 中
            // 下面开始处理 postProcessBeanFactory  -> 是在 BeanFactoryPostProcessor 中
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        } else {
            // Invoke factory processors registered with the context instance.
            // 不是 BeanDefinitionRegistry 则是普通 BeanFactory 直接执行 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
        // 下面开始执行 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.
        // 执行实现 PriorityOrdered 的
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
        // 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);
    
        // 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);
    
        // Clear cached merged bean definitions since the post-processors might have
        // modified the original metadata, e.g. replacing placeholders in values...
        // 清空不必要的元数据信息
        beanFactory.clearMetadataCache();
    }
    

    上面总体可以分为两部分:

    1. 执行 BeanDefinitionRegistryPostProcessor 接口里面的两个方法:postProcessBeanDefinitionRegistry 和 postProcessBeanFactory。
    2. 执行 BeanFactoryPostProcessor 接口里面的 postProcessBeanFactory 方法。

    以第一部分为例:

    1. 首先判断传入的 BeanFactory 是否为 BeanDefinitionRegistry
      1. 声明两个 List 集合,regularPostProcessors 用来存储 BeanFactoryPostProcessor,registryProcessors 用来存储 BeanDefinitionRegistryPostProcessor
        1. 循环 beanFactoryPostProcessors,这个就是我们使用 API 方式添加进来的 BeanFactoryPostProcessor。
        2. 在循环中 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 会被执行,也就是说我示例的那个添加 BeanDefinition 演示的方法会被执行。
      2. 开始执行 Spring 自己的 BeanDefinitionRegistryPostProcessor, 处理顺序为 PriorityOrdered, Ordered, and the rest
        1. 循环,将对应的 BeanDefinitionRegistryPostProcessor 添加到 currentRegistryProcessors 集合和processedBeans集合表示为已经处理。
        2. 排序后添加到第一步的 registryProcessors 中。
        3. 调用 invokeBeanDefinitionRegistryPostProcessors 执行所有的 Processor 里面的 postProcessBeanDefinitionRegistry 方法
      3. 执行完 1 和 2 之后,所有的 postProcessBeanDefinitionRegistry 已经被执行完了,但是两个集合(registryProcessors、regularPostProcessors)里面的 postProcessBeanFactory 方法还没有被执行。最后会循环执行。
    2. 如果不是 BeanDefinitionRegistry 类型,则直接执行传入的 beanFactoryPostProcessors 即可。

    下面是对应的代码截图

    以上只是这个方法的前半部分,执行了 BeanDefinitionRegistryPostProcessor 里面的 postProcessBeanDefinitionRegistry 和 postProcessBeanFactory。

    因为还有直接实现 BeanFactoryPostProcessor 的处理器,下面则开始处理 BeanFactoryPostProcessor 的处理器。过程和上面类似。

    总结

    通过以上的阅读,对 invokeBeanFactoryPostProcessors(beanFactory); 这一步方法进行总结。

    BeanFactoryPostProcessor 作用

    BeanFactoryPostProcessor 主要作用是在注册 BeanDefinition 之后,在 Bean 初始化之前,修改 BeanDefinition 的信息。

    BeanFactoryPostProcessor 有个实现叫 BeanDefinitionRegistryPostProcessor,它可以额外的注册新的 BeanDefinition 到容器中。

    流程概述

    1. 这一步主要是处理 BeanFactoryPostProcessor,分为两步。
    2. 执行 BeanDefinitionRegistryPostProcessor 接口里面的两个方法:postProcessBeanDefinitionRegistry 和 postProcessBeanFactory。
    3. 执行 BeanFactoryPostProcessor 接口里面的 postProcessBeanFactory 方法。

    相关推荐

  • 相关阅读:
    android工程下assets与raw文件夹
    eclipse增加jar包方式对比
    跳出内循环,继续下一次外循环的写法
    ImportError: cannot import name 'BaseDataset' from 'src.dataset'
    神经网络中的反向传播法
    Pytorch中ndarray tensor list互转
    Python运行语法错误:IndentationError: unindent does not match any outer indentation level
    module 'torch' has no attribute 'gesv'
    极大似然估计
    Gaussian Processes
  • 原文地址:https://www.cnblogs.com/liuzhihang/p/source-spring-11.html
Copyright © 2011-2022 走看看