一、定义

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,进行属性注入和初始化。

AbstractAutoProxyCreator#postProcessBeforeInstantiation的更多相关文章

  1. spring异常-aoperror at :0 formal unbound in pointcut

    八月 17, 2016 10:15:21 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRe ...

  2. Java AOP nested exception is java.lang.NoClassDefFoundError: org/aopalliance/aop/Advice || Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0' 两个异常解决办法

    贴出applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans ...

  3. Pointcut is not well-formed: expecting 'identifier' at character position 0

    异常如下: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDa ...

  4. Spring AOP报错

    八月 01, 2016 10:08:48 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRe ...

  5. Caused by: java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWo

    1.错误描述 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] [ -nonaming ] { -help ...

  6. 解决 spring-cloud-starter-zipkin 启动错误

    应用场景:Spring Boot 服务添加 Zipkin 依赖,进行服务调用的数据采集,然后进行 Zipkin-Server 服务调用追踪显示. 示例pom.xml配置: <parent> ...

  7. Spring中的AOP 专题

    Caused by: java.lang.IllegalArgumentException: ProceedingJoinPoint is only supported for around advi ...

  8. 开发Spring过程中几个常见异常(二):Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'a' define

    本异常是小编在运行自己另外一篇博文中的例子时遇到的.(附博文:http://www.cnblogs.com/dudududu/p/8482487.html) 完整异常信息: 警告: Exception ...

  9. spring源码分析之初始化过程

    1.org.springframework.web.context.ContextLoaderListener 一个ServletContextListener,web容器启动监听器 1.1内有成员C ...

  10. Linux下Tomcat项目启动报错

    Linux下Tomcat项目启动报错 org.springframework.beans.factory.CannotLoadBeanClassException: Error loading cla ...

随机推荐

  1. Robot Framework 自动化测试部署常见问题及处理方法(二)

    书接上文 4.使用Open Browser关键字打开浏览器报错"WebDriverException: Message: 'geckodriver' executable needs to ...

  2. 多方安全计算(6):MPC中场梳理

    学习&转载文章:多方安全计算(6):MPC中场梳理 前言 诚为读者所知,数据出域的限制约束与数据流通的普遍需求共同催生了数据安全计算的需求,近一两年业界又统将能够做到多方数据可用不可见的技术归 ...

  3. LeetCode刷题:runtime error: reference binding to null pointer of type 'int' (stl_vector.h)报错请教

    题目:https://leetcode.cn/problems/merge-intervals/ 错误代码: // 思路初探:做了很多道类似区间操作的题目了.本题就是尽可能少的创建新区间 // 1.首 ...

  4. ThreeJs-14HTML混合3D渲染

    一.css渲染器基本使用 使用场景:经常在一些3D物体左右还会跟随一些文字等,实际都是标签,应用场景非常广泛 先完成基本的3D,月球围绕地球转,这里就是给月球加了sin函数 然后现在就先创建一个标签体 ...

  5. Xshell不可以删除,退格^H

    文件→属性→终端→键盘,把delete和backspace序列改为 ASCII 127即可.

  6. SnowFlake雪花算法

    简介 自然界不存在两片完全一样的雪花,每一片都是独一无二的,雪花算法的命名由此而来,所有雪花算法表示生成的ID唯一,且生成的ID是按照一定的结构组成. 组成结构 上图可以看到雪花算法的结构由四部分组成 ...

  7. OpenLayers 修改 Feature 的 Style 后不实时更新问题,解决惹~~~

    比如我修改了 字体 feature.getStyle().getText().setFont('12px sans-serif') 地图上没有及时更新,需要缩放或者进行其他操作才可以 这个时候调用 l ...

  8. Opencv | 图形学 | Mingw64 | 如何正确地用MinGW64编译与配置vscode的Opencv环境

    如何正确地用MinGW64编译与配置vscode的Opencv环境 1.前情提要 最近有关于图形学的授课,教授开始布置的上机打码的代码实现作业了.虽说教授为了让我们省心,直接就整了个环境已经配置好的几 ...

  9. 使用电阻网络实现的vga驱动电路,fpga驱动vga显示器验证,代替gm7123芯片

    之前驱动vga,要么是直接使用fpga管脚直接驱动,颜色为8原色 使用线缆 vs,hs,r,g,b一共五根线,三原色要么是0要么是1,所以色彩最多8种,rgb组合 若要实现真彩色驱动,如rgb888, ...

  10. ccrc 评审资料该如何编写【通用型】

    核心思路:各个过程中和安全检查内容进行对应 首先应该有信息安全服务规范 其次准备好平时项目的所有文档 第三,参照规范内容,每一项要求[准备.需求.设计.编码.测试.验收.维保]在原有文档上进行筛选和补 ...