Spring 源码学习 11:invokeBeanFactoryPostProcessors

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

前言


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 演示的方法会被执行。
  1. 开始执行 Spring 自己的 BeanDefinitionRegistryPostProcessor, 处理顺序为 PriorityOrdered, Ordered, and the rest
  1. 循环,将对应的 BeanDefinitionRegistryPostProcessor 添加到 currentRegistryProcessors 集合和processedBeans集合表示为已经处理。
  2. 排序后添加到第一步的 registryProcessors 中。
  3. 调用 invokeBeanDefinitionRegistryPostProcessors 执行所有的 Processor 里面的 postProcessBeanDefinitionRegistry 方法
  1. 执行完 1 和 2 之后,所有的 postProcessBeanDefinitionRegistry 已经被执行完了,但是两个集合(registryProcessors、regularPostProcessors)里面的 postProcessBeanFactory 方法还没有被执行。最后会循环执行。
  1. 如果不是 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 方法。

网络异常,图片无法展示
|



目录
相关文章
|
6月前
|
监控 Java 应用服务中间件
微服务——SpringBoot使用归纳——为什么学习Spring Boot
本文主要探讨为什么学习Spring Boot。从Spring官方定位来看,Spring Boot旨在快速启动和运行项目,简化配置与编码。其优点包括:1) 良好的基因,继承了Spring框架的优点;2) 简化编码,通过starter依赖减少手动配置;3) 简化配置,采用Java Config方式替代繁琐的XML配置;4) 简化部署,内嵌Tomcat支持一键式启动;5) 简化监控,提供运行期性能参数获取功能。此外,从未来发展趋势看,微服务架构逐渐成为主流,而Spring Boot作为官方推荐技术,与Spring Cloud配合使用,将成为未来发展的重要方向。
203 0
微服务——SpringBoot使用归纳——为什么学习Spring Boot
|
1月前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
5月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
387 70
|
5月前
|
Java Spring
Spring框架的学习与应用
总的来说,Spring框架是Java开发中的一把强大的工具。通过理解其核心概念,通过实践来学习和掌握,你可以充分利用Spring框架的强大功能,提高你的开发效率和代码质量。
147 20
|
10月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
265 2
|
6月前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
120 0
|
8月前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
311 7
|
9月前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
204 2
|
10月前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
220 9