AbstractAutoProxyCreator#postProcessBeforeInstantiation

news/2025/3/22 2:07:12/文章来源:https://www.cnblogs.com/jock766/p/18786141

一、定义

postProcessBeforeInstantiation 是 Spring AOP 动态代理的核心扩展点,通过提前创建代理对象优化性能,并支持丰富的自定义逻辑(如事务、安全)


二、代码分析

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {Object cacheKey = getCacheKey(beanClass, beanName);if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {if (this.advisedBeans.containsKey(cacheKey)) {return null;}if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return null;}}// Create proxy here if we have a custom TargetSource.// Suppresses unnecessary default instantiation of the target bean:// The TargetSource will handle target instances in a custom fashion.if (beanName != null) {TargetSource targetSource = getCustomTargetSource(beanClass, beanName);if (targetSource != null) {this.targetSourcedBeans.add(beanName);Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}}return null;
}


1、生成缓存键

  • 作用: 根据 Bean 的类名或 Bean 名称生成唯一的缓存键,用于后续缓存操作


2、检查是否需要处理当前 Bean

  • 作用: 确定当前 Bean 是否已经被处理过

  • 条件解释:

    • beanName == null: 处理匿名 Bean。

    • !targetSourcedBeans.contains(beanName): 确保 Bean 未被标记为已处理。

  • 集合说明: targetSourcedBeans: 记录已通过自定义 TargetSource 处理的 Bean,避免重复代理


3、查是否已处理 或 需跳过

  • 分支 1: 如果缓存键已经存在于advisedBeans中,直接返回null。这说明这个Bean已经被处理过,不需要再次处理,直接跳过

  • 分支 2:

    • isInfrastructureClass(beanClass): 判断是否为 Spring 内部类(如 Advisor, Advice),实现逻辑: 检查类是否实现 Advice、Advisor 等接口

    • shouldSkip(beanClass, beanName): 根据用户配置或注解(如 @SkipAop)决定跳过代理

    • 标记为不代理: 将 cacheKey 对应值设为 FALSE,避免重复检查


4、处理自定义 TargetSource

  • 作用: 检查是否有自定义的 TargetSource,若有则创建代理。

  • getCustomTargetSource 逻辑:

    • 查找 Bean 定义中是否指定了 TargetSource。

    • 示例:通过 @Scope 配置 proxyMode 或 XML 中定义 target-source 属性。

  • 示例场景:

    • 动态数据源切换: 根据请求上下文动态选择数据源实现。


5、创建代理对象

  • 步骤详解:

    • 1、标记为已处理: 将 beanName 加入 targetSourcedBeans。

    • 2、获取拦截器:

      • getAdvicesAndAdvisorsForBean: 收集匹配该 Bean 的所有拦截器(如事务、日志 Advice)。

      • 匹配逻辑: 根据切点表达式(Pointcut)判断拦截器是否适用

    • 3、生成代理:

      • createProxy: 根据配置选择 JDK 动态代理或 CGLIB。

        • JDK 代理: Bean 实现至少一个接口。

        • CGLIB 代理: Bean 无接口或强制使用 CGLIB。

      • 参数 SingletonTargetSource: 确保代理持有单例目标对象


6、默认返回 null

  • 作用: 若无自定义 TargetSource 或无需代理,返回 null,触发 Spring 默认实例化流程。

  • 后续流程: Spring 将调用构造器创建 Bean,进行属性注入和初始化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/902755.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Day20_javascanner_struct

Java JavaDoc javadoc命令是用来生成自己API文档的 参数信息: @author 作者名 @version 版本号 @since 指明需要最早使用的jdk版本 @param 参数名 @return 返回值情况 @throws 异常抛出情况 /*** @author XXX* @version 1.0* @since 1.8*/public class Doc {String name;/*** …

k8s基本字段

k8s基本字段 limits字段 此字段限制的是硬件的资源,如果容器尝试申请超过限制的内存将会终止容器 requests字段 此字段限制的是容器可以请求的资源,可以超出request申请额外的资源,但是不能超过limits, 500m等于0.5个CPU本地临时性文件,采用这种配置时,你会把所有类型的临…

【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(3)

比赛链接 本文发布于博客园,会跟随补题进度实时更新,若您在其他平台阅读到此文,请前往博客园获取更好的阅读体验。 跳转链接:https://www.cnblogs.com/TianTianChaoFangDe/p/18786128 开题 + 补题情况 很菜的一把,就开了三个签到题,1001 Lucas 定理花了好久才看出来,明明…

51单片机学习笔记-3

串口通信UART(universal asynchronous receiver transmitter,通用异步收发器):可用来实现串口通信。串口硬件:基础串口包含TXD/RXD两个通信线,他们交叉连接。(如DB9通常使用2(RXD),3(TXD),5(GND)。) 当串口两头电平标准不一样时,需要叫电平转换芯片。TTL电平:5V表示1,…

微信小程序 -2025/3/22

HttpClient 介绍:核心api发送请求步骤小程序目录结构小程序页面组成微信登录 发送请求

应用打包测试

用HBuilder打包了一个之前写着玩的html页面

小白与Android Studio的初遇

新手小白在Android Studio上运行程序的时候遇到俩问题,通过在网上各种找解决方法,最终解决了(然后就想起来继续写博客这件事儿了)。 【第一个问题】关于“Error runningapp:No target device found”。就是它找不到设备(虚拟机或者真机),所以配置虚拟机就行了。 (当我以…

20234220 实验一《Python程序设计》实验报告

20234220 2024-2025-2 《Python程序设计》实验一报告 课程:《Python程序设计》 班级: 2342 姓名: 马燕秋 学号:20234220 实验教师:王志强 实验日期:2025年3月18日 必修/选修: 公选课 1.实验内容 1.熟悉Python开发环境; 2.练习Python运行、调试技能; 3.编写程序,练…

Echarts-普通地图和3D地图实现

效果图实现代码 <template><div class="app"><h1>普通地图----------------</h1><div class="map-container" ref="map_ref"></div><h1>3D地图----------------</h1><div class="map-c…

Navicat Premium 16 For Mac 激活,无限试用,非破解,官网安装程序,Mac版Navicat无限试用

Navicat Premium 16 For Mac 激活,无限试用,非破解,官网安装程序,Mac版Navicat无限试用Navicat Premium是一个可多重连线资料库的管理工具,它可以让你以单一程式同时连线到 MySQL、SQLite、Oracle、MariaDB、Mssql、及 PostgreSQL 资料库,让管理不同类型的资料库更加的方…

Vue3 slot

6.9. 【slot】 1. 默认插槽父组件中:<Category title="今日热门游戏"><ul><li v-for="g in games" :key="g.id">{{ g.name }}</li></ul></Category> 子组件中:<template><div class="item&…