关于spring:Spring-源码学习-11invokeBeanFactoryPostProcessors

38次阅读

共计 13118 个字符,预计需要花费 33 分钟才能阅读完成。

前言

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 办法。

相干举荐

  • Spring 源码学习 10:prepareBeanFactory 和 postProcessBeanFactory
  • Spring 源码学习 09:refresh 大略流程
  • Spring 源码学习 08:register 注册配置类

正文完
 0