spring扩展点二:自定义beanPostProcessor原理解析

SpringBoot -【BeanPostProcessor】基础使用及应用场景 BeanPostProcessor是Spring框架中一个重要的接口,允许开发人员在Bean对象初始化的不同阶段插入自定义逻辑。它提供了灵活性和可扩展性,可用于简化依赖注入、实现面向切面编程、优化配置管理等方面。然而,使用BeanPostProcessor需要注意避免循环依赖、谨慎处理Bean初始化逻辑、注意性能影响等常见问题。通过正确使用注意事项,可以更安全、高效地利用BeanPostProcessor来增强Spring应用程序的功能。 阅读详情

beanPostProcessor是我在学习spring源码中,目前看到扩展最多的一个接口,比如:aop、spring事务、初始化方法回调,都是对该接口的扩展和实现,除了spring本身的框架,比如dubbo的ReferenceAnnotationBeanPostProcessor,这个扩展类就是一个后置处理器,用来解析@Reference注解的

bean后置处理器呢,spring在初始化bean的流程中,已经定义好了先执行后置处理器的哪个方法,后执行哪个方法,所以,我们在扩展的时候,要熟知这些方法执行位置以及先后顺序,根据这些,来明确自己的业务需求需要在哪个步骤进行扩展

我们只需要按照不同的beanPostProcess子类去实现即可

前言

不管是 我们实现的哪个扩展类,都需要考虑两个问题
1.我们扩展了之后,如果把我们自定义的扩展类放到spring容器中
2.放到容器中之后,是否会按照我们设想的步骤去调用
对于第一点,我们可以直接通过@Component注解,将beanPostProcessor作为一个普通的bean,放到beanDefinitionMap中即可,因为在spring启动的流程中,有一步是单独去注册初始化所有的后置处理器,
所以,对于第一点,我们只需要记住,只要将beanPostProcessor作为一个bean添加到beanDefinitionMap中即可,spring会自动帮我们去初始化这个后置处理器

对于第二点,我们提供了一个实现类之后,spring是如何将我们自己定义的beanPostProcessor作用于初始化过程中的呢?也和上面说的注册beanPostProcessor有关系,在spring将所有的后置处理器初始化之后,会将初始化好的后置处理器,放到一个集合中,spring在每次去调用后置处理器方法的时候,会从这个list集合中,获取到所有的符合条件的后置处理器,去过滤

其实对于spring中后置处理器的扩展机制原理,我觉得搞懂了这两句话,就全明白了

关于第一点,如何将我们提供的后置处理器放入到spring容器中,可以参考之前的笔记spring源码:注册后置处理器

注册后置处理器

第二点:
我们先说我们自定义的后置处理器,是存储在哪里的
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors()
这个方法,是spring来初始化所有后置处理器的,那其中在初始化完成之后,有一步比较关键的操作
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, internalPostProcessors);

这三行代码,调用的是同一个逻辑,只是入参不同而已,看下方法的具体处理逻辑

private static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

    for (BeanPostProcessor postProcessor : postProcessors) {
      beanFactory.addBeanPostProcessor(postProcessor);
    }
  }


  @Override
  public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    // Remove from old position, if any
    this.beanPostProcessors.remove(beanPostProcessor);
    // Track whether it is instantiation/destruction aware
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
      this.hasInstantiationAwareBeanPostProcessors = true;
    }
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
      this.hasDestructionAwareBeanPostProcessors = true;
    }
    // Add to end of list
    this.beanPostProcessors.add(beanPostProcessor);
  }

这里最为重要的是最后一行代码,将beanPostProcess放入到private final List beanPostProcessors = new CopyOnWriteArrayList<>();这个集合中,这个集合在后面的源码,我们还会看到,先有个印象

自定义的后置处理器如何生效

我们以第五个后置处理器方法org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
为例,这个方法是在属性注入之前被调用的,用来判断是否需要进行属性注入,
1、如果这个方法返回false,表示当前bean无需进行属性注入
2、那假如此时我有一个需求,需要对PayOrderService这个类进行处理,这个类中无需进行属性注入,这里我只是举一个例子,那此时,我就可以自己提供一个InstantiationAwareBeanPostProcessor的实现类,然后在实现类的postProcessAfterInstantiation()方法中,判断,如果当前初始化的bean是payOrderService,就返回false
3、需要注意的是,如果我们自己去扩展了实现类,一定要在实现方法中加上对bean的判断,否则,所有的bean都不会进行属性注入,为什么?因为每个bean在初始化的时候,都会调用我们自己的实现类,去判断是否要属性注入

这里有一个点要解释,为什么是InstantiationAwareBeanPostProcessor的方法,因为InstantiationAwareBeanPostProcessor继承了BeanPostProcessor,所以,这也是一个后置处理器的扩展接口;
针对第三点,一定要判断bean是否是自己要跳过属性注入的bean,可以去看下spring源码中,默认的实现方法,基本上都是返回true,都是需要属性注入的

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

boolean continueWithPropertyPopulation = true;

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
      InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
      if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
        continueWithPropertyPopulation = false;
        break;
      }
    }
  }
}

if (!continueWithPropertyPopulation) {
  return;
}

这一段代码,就是对postProcessAfterInstantiation的处理,可以看到,在源码中,会先判断当前beanDefinition是否是合成beanDefinition,然后再判断当前容器中,是否存在InstantiationAwareBeanPostProcessor的实现类

protected boolean hasInstantiationAwareBeanPostProcessors() {
  return this.hasInstantiationAwareBeanPostProcessors;
}

hasInstantiationAwareBeanPostProcessors在什么时候被赋值的?在上面注册后置处理器这里的addBeanPostProcessor方法中

判断完这些之后,会接着去遍历getBeanPostProcessors()返回的list集合

public List<BeanPostProcessor> getBeanPostProcessors() {
	return this.beanPostProcessors;
}

前面有说过,beanPostProcessors这个list会在后面出现使用到,就是这里
所以这里就解释了,我们自定义的beanPostProcess实现类,是如何生效的?
spring源码中,在每次进行后置处理器方法调用的时候,是会遍历容器中所有的后置处理器,依次调用其后置处理器方法进行处理

总结

最后做一个小总结吧,如果我们要扩展一个beanPostProcess的实现类,这个实现类要根据我们想要做的事情,来实现不同的beanPostProcess接口,然后通过@Component注解将实现类注入到spring容器中,就无需再做其他操作了,剩下的,spring就帮我们自己完成了调用
只是,我们在扩展的时候,需要明白自己扩展的业务逻辑要如何实现

Spring Boot 生命周期与核心扩展点全解析(含实操案例) / 1. 实现扩展类@Override// 往环境中添加自定义属性// 将自定义属性添加到环境中(优先级低于配置文件)System.out.println("ApplicationContextInitializer:已添加自定义系统属性");// 2. 注册扩展类(两种方式任选其一)// 方式1:在启动类中手动注册// 添加自定义Initializer// 方式2:通过META-INF/spring.factories配置(推荐,解耦) 阅读详情

相关推荐

【Spring源码】7. 如何添加自定义的BeanFactoryPostProcessor

如何添加自定义的BeanFactoryPostProcessor? 新建两个类,分别实现BeanFactoryPostProcessor接口和BeanDefinitionRegistryPostProcessor接口(任选一个也可以,本文为了介绍全面,两个同时举例🌰)

aqin1012的博客 2220

Spring扩展之BeanPostProcessor

作用 BeanPostProcessor,顾名思义是bean后置处理器,是 Spring 的扩展点之一。通过自定义 BeanPostProcessor 可以实现对 Bean 的修改,用于在bean实例化后,要初始化的前后对bean进行处理 public interface BeanPostProcessor { /** * 在初始化前调用 */ @Nullable default Object postProcessBeforeInitialization(Object bean, Stri

指尖凉的博客 1400

Verilog与综合:数字逻辑的代码化革命及其未来挑战

本文深入探讨Verilog硬件描述语言与逻辑综合技术在数字芯片设计中的革命性作用。Verilog实现了数字逻辑的代码化描述,而综合技术则将其自动转换为门级网表,大幅提升设计效率。文章重点分析了在先进工艺节点下面临的时序、功耗和物理效应等挑战,并展望了AI驱动综合优化的未来发展方向。

postgres8guard的博客 801

Spring扩展之BeanPostProcessor接口

目录 一、定义 二、自定义BeanPostProcessor的实现类 三、BeanPostProcessor的注册过程分析 四、BeanPostProcessor的执行过程分析 五、BeanPostProcessor的常用子类和实现类 六、总结 一、定义 BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口,它可以在spring容器实例化bean之后,在执行bean的初始化方法前后,允许我们自定义修改新的bean实例,如修改bean的属性,可以给bean生

weixiaohuai的博客 4305

Arm Neoverse CMN-700 QoS与PrefetchTarget架构解析

在现代多核处理器系统中,内存访问性能优化是提升整体效能的关键。QoS(服务质量)技术通过优先级调控机制,确保关键任务获得更高的缓存带宽和内存访问权限。PrefetchTarget作为预取技术的一种实现,能够显著降低内存访问延迟,特别适用于AI训练和数据库系统等高性能计算场景。Arm Neoverse CMN-700通过RN SAM模块实现了硬件级的地址范围检测和优先级调控,支持最多8个独立内存区域的QoS配置。测试数据显示,合理配置QoS可使关键任务延迟降低40%,而PrefetchTarget技术则能减少

weixin_36197669的博客 314

【嵌入式笔试题】C语言笔试题(4)

嵌入式C语言综合笔试题

m0_74055118的博客 1067

【Spring】BeanFactoryPostProcessor的使用与执行原理分析

BeanFactory的后置处理器就是BeanFactoryPostProcessor接口,该接口有一个方法postProcessBeanFactory,这个方法会在BeanFactory初始化之后调用,这时所有的bean定义(BeanDefinition)已经保存加载到beanFactory,但是bean的实例还未创建,可以通过BeanFactory对BeanDefinition的内容进行修改,也可以增加BeanDefinition。 BeanFactoryPostProcessor 先自定义一个Bean

morris 2260

Ubuntu 24.04 极速部署 Dify:从零到一的保姆级实践

本文详细介绍了在Ubuntu 24.04系统上快速部署Dify的完整教程,从环境准备到部署验证,再到深度优化和安全加固,提供了一套保姆级的实践指南。通过使用Docker和Docker Compose,结合国内镜像源加速,帮助用户高效完成Dify的安装和配置,确保系统稳定运行。

weixin_42662293的博客 245

Springboot扩展点之BeanPostProcessor

在程序中我们可以自定义注解并标到相应的类上,当个类注册到Spring容器中,并实例化完成后,希望触发自定义注解对应的一些其他操作的时候,就可以通过BeanPostProcessor来实现。

凡夫编程 6015

多跳问答技术解析:从原理到金融领域实践

多跳问答(Multi-hop QA)是自然语言处理中的高级任务,要求系统通过多步推理整合分散信息来回答问题。其核心技术在于理解文档间的复杂关联,相比单跳问答需要更精细的数据集设计和模型架构。在金融、医疗等专业领域,多跳问答能有效处理如'腾讯大股东投资的港股上市公司'这类需要串联多个信息点的问题。典型实现方案包括MR-Search框架的三级检索器设计,分别处理实体召回、关系匹配和数值比较。当前最佳实践表明,结合稠密检索与稀疏检索的混合策略,配合动态路由机制,能在保持较高精度的同时控制计算成本。这类技术在金融风

weixin_42566072的博客 606

【WRF理论第十四期】 VEGPARM.TBL 文件详解

WRF 读取 VEGPARM.TBL 文件

WW、forever的博客 576

Spring 源码解读:自定义实现BeanPostProcessor的扩展点

在Spring的生命周期管理中,`BeanPostProcessor`是一个非常重要的扩展点。它允许开发者在Bean初始化的前后插入自定义的逻辑,从而实现更灵活的Bean管理。`BeanPostProcessor`是Spring框架中用于对Bean实例进行修改的机制之一。通过实现该接口,开发者可以在Bean创建过程中添加额外的逻辑。在本篇文章中,我们将手动实现一个类似于Spring的`BeanPostProcessor`,展示如何在Bean初始化的前后进行扩展处理,并与Spring的....

捕风捉你 · 星桥API接入与大模型实战 1535

手把手入门YOLO到改进优化教程 | 【P1基础篇】YOLOv8网络架构原理

本节先来学习基础知识,以YOLOv8进行讲解入门, 拿YOLOv8入手掌握YOLO的底层逻辑 ,也可以基于此来轻松学习后面更新的YOLO系列 (大部分YOLO版本的核心思想一致,更新是基于旧版本做结构升级、优化策略,学习成本会越来越低)。

嵌入式阿齐Archie 2万+

简单易懂的Spring扩展点详细解析,看不懂你来打我

以上就是本文对Spring扩展点的所有介绍,基本上已经涵盖了Spring里面比较重要的扩展点,当然还有其他的一些扩展点没有介绍到,但是由于篇幅关系,就不全部罗列了。总结性的文字就不多说了,因为本文的字已经够多的了,这里就放两张图,供大家细品吧。

weixin_43889578的博客 6813

【swjtu】算法实验2.4分析算法时间复杂度

分析给定算法的时间复杂度。 上机实验,绘制不同输入情况下的运行时间曲线,并与(1)中的分析结果进行比较。 撰写相应的实验报告,实验报告内容包括:实验目的、实验任务、 实验环境、实验步骤、实验结果及其分析以及实验总结等部分内容。

qq_52046937的博客 731

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Spring的扩展点都有哪些

目录前言一、扩展原理1、原始扩展点1.1、BeanFactoryPostProcessor1.2、BeanPostProcessor1.3、ApplicationListener2、衍生的扩展点2.1、InstantiationAwareBeanPostProcessor2.2、SmartInstantiationAwareBeanPostProcessor3、内置的重要后置处理器3.1、ConfigurationClassPostProcessor3.2、CommonAnnotationBeanPostP

kaixinnijiutiaowu的博客 3938

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【Spring系列-10】Spring 核心扩展点全解析

Spring核心扩展点解析:BeanFactoryPostProcessor和BeanPostProcessor机制详解 本文深入解析Spring框架的两个核心扩展点:BeanFactoryPostProcessor和BeanPostProcessor。前者在Bean定义加载完成后、实例化前提供修改BeanDefinition的机会,适用于动态调整配置(如数据源连接池大小);后者则在Bean初始化前后对实例进行处理,常用于AOP增强(如方法执行时间统计)。通过源码分析揭示其执行顺序及实现原理,并配以实际应用

专注后端技术架构,AI技术分享 975

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

万字长文带你窥探Spring中所有的扩展点

Spring的核心思想就是容器,当容器refresh的时候,外部看上去风平浪静,其实内部则是一片惊涛骇浪,汪洋一片。Springboot更是封装了Spring,遵循约定大于配置,加上自动装配的机制。很多时候我们只要引用了一个依赖,几乎是零配置就能完成一个功能的装配。由spring提供的、在容器或bean生命周期各个阶段、供spring框架回调使用的函数方法,即为扩展点。扩展点体现了Spring框架的灵活性、业务亲和性。

SevenCoding的博客 3381

深入解析Spring IoC容器:从启动流程到BeanPostProcessor扩展点

在软件工程领域,控制反转(Inversion of Control,IoC)是一种颠覆传统编程范式的设计原则。Spring框架将这一原则具象化为IoC容器,成为其架构体系中最核心的组件。理解IoC容器的本质,是掌握Spring框架底层原理的关键切入点。在Spring框架中,BeanPostProcessor是一个极其强大的扩展点,它允许开发者在Bean实例化、依赖注入以及初始化前后插入自定义逻辑。通过实现这个接口,我们可以对Spring容器中的Bean进行深度定制,甚至改变其默认行为。

zuiyuelong的博客 1598

Spring扩展点源码分析:BeanPostProcessor与FactoryBean

Spring扩展点源码分析:BeanPostProcessor与FactoryBean 本文深入分析了Spring框架中两个核心扩展点BeanPostProcessor和FactoryBean的实现机制。BeanPostProcessor在Bean生命周期中提供初始化前后的拦截能力,支持AOP代理创建、注解处理等关键功能;FactoryBean则提供了特殊的Bean创建机制,允许通过编程方式控制复...

gitblog_01090的博客 416

Spring Boot 核心接口与扩展点详细指南

本文详细介绍了Spring Boot的核心接口与扩展点,涵盖容器启动、环境配置和Bean定义等关键阶段。主要内容包括: 容器启动阶段:ApplicationContextInitializer用于早期配置,SpringApplicationRunListener监听启动事件,ApplicationRunner和CommandLineRunner在启动后执行逻辑。 环境配置:EnvironmentPostProcessor动态修改环境变量,PropertySourceLoader支持自定义配置文件加载。

在技术的广袤天地里,本博客如精准罗盘。剖析前沿科技,深掘代码奥秘,以精炼笔触,带您穿越复杂技术迷宫,速达知识彼岸。 3374

Spring之BeanPostProcessor

BeanPostProcessor是bean的后置处理器,会影响bean的一些行为甚至是替换原有的bean。了解BeanPostProcessor之前最好有对BeanFactoryPostProcessor有一些了解,不了解的小伙伴可以查看我的上篇博文Spring之BeanFactoryPostProcessor2.BeanPostProcessor是在什么时机注入到Spring中的。

好记性不如烂笔头 6416

Spring 扩展点 - BeanPostProcessor

前面有分享过链接Spring如何实现AOP的文章,里面有提到过是基于的前后处理实现,那么在本篇文章中我们自定义扩展,手动实现对Bean的代理增强。1.通过扩展Spring的,对Bean进行代理增强。2.@TimeDetect注解,灵活的监控每个方法执行时间。3.,监听超时方法,自定义监听逻辑。项目连接。...

z_Jimmy的博客 617

Spring 中 FactoryBean与 BeanPostProcessor 的深度解析

本文深入剖析了Spring框架中两个核心接口FactoryBean和BeanPostProcessor的工作原理与应用。FactoryBean作为Bean工厂接口,通过getObject()方法自定义Bean创建逻辑,支持单例/原型模式,在MyBatis等第三方库集成中发挥关键作用。BeanPostProcessor则作为Bean增强器,在Bean初始化前后插入统一逻辑,广泛应用于AOP代理、属性验证等场景。文章还特别分析了BeanPostProcessor对FactoryBean产物的特殊处理机制,帮助开

weixin_44289947的博客 1051

Spring常用扩展点之BeanPostProcessor篇(一)

Spring常用扩展点之BeanPostProcessor篇(一)

墨言的博客 9067
上一篇: spring扩展点一:BeanDefinitionRegistryPostProcessor在框架中的应用
下一篇: mergeBeanDefinition原理
小小少年_
博客等级 码龄10年 63粉丝 146原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值