SpringAOP的底层实现原理

Spring AOP 的本质,是在 Bean 创建阶段,通过动态代理技术,对目标对象进行增强,在不修改原有业务代码的情况下,统一织入横切逻辑。

文章目录

一、为什么要用AOP?(使用场景)

想象一个典型业务:

java 复制代码
下单()
  校验参数
  打日志
  校验权限
  开启事务
  核心业务
  提交事务

问题来了👇

  • 日志、事务、权限 到处都有

  • 改一次,要改一堆类

  • 业务代码被"杂音"淹没

于是 Spring 说:

👉 这些"横着切进业务"的逻辑,交给 AOP 管

这些就是 横切关注点(Cross-Cutting Concerns)

  • 事务

  • 日志

  • 权限

  • 监控

  • 接口幂等


二、SpringAOP的核心组成

概念 作用
Aspect(切面) 封装横切逻辑的类
Advice(通知) 具体增强逻辑(方法)
Pointcut(切点) 决定拦截哪些方法
JoinPoint(连接点) 被拦截的方法
Target(目标对象) 原始业务对象
Proxy(代理对象) Spring 返回给你的对象
一句话串起来👇

切面 = 切点 + 通知,Spring 用代理对象替代目标对象执行方法


三、AOP的核心流程

1. 在Bean创建阶段动手

Spring AOP 不是运行时随便插的,而是在:

Bean 初始化完成后,放入 IOC 容器之前

流程简化版:

csharp 复制代码
Bean 实例化
  ↓
属性注入
  ↓
初始化(init)
  ↓
👉 AOP 判断是否需要代理
  ↓
生成代理对象
  ↓
放入 IOC 容器

所以你从容器里拿到的对象,已经是代理对象了


2. 关键角色 :BeanPostProcessor

Spring AOP 的入口是:

复制代码
AbstractAutoProxyCreator(Bean 后置处理器)

它干的事只有一句话:

复制代码
判断当前 Bean 是否匹配切点,如果匹配,就创建代理对象

四、Spring AOP 的两种代理方式(必问)

1. JDK动态代理

条件 :目标类 实现了接口

原理:

  • 基于 InvocationHandler

  • 代理的是 接口方法

java 复制代码
Proxy.newProxyInstance(...)

特点:

  • 只能代理接口

  • 生成代理类快

  • Spring 默认优先使用


2. CGLIB动态代理

条件

  • 没有接口

  • 或强制使用 proxyTargetClass = true

原理:

  • 继承目标类

  • 通过 方法拦截器(MethodInterceptor)

特点:

  • 代理的是类

  • 不能代理 final 方法

  • 性能在现代 JVM 下已非常接近 JDK 代理


五、方法调用时发生了什么?

当你调用代理对象的方法:

scss 复制代码
代理对象.method()
  ↓
拦截器链(Interceptor Chain)
  ↓
@Before
  ↓
@Around(前)
  ↓
目标方法
  ↓
@Around(后)
  ↓
@After
  ↓
@AfterReturning / @AfterThrowing

本质是一个 责任链模式

六、事务是AOP的经典落地案例

java 复制代码
@Transactional
public void save() {
    // 业务代码
}

Spring 干了什么?

  1. 解析 @Transactional

  2. 生成事务切面 TransactionInterceptor

  3. 方法前:

    • 开启事务
  4. 方法后:

    • 正常 → 提交

    • 异常 → 回滚

👉 事务本质 = AOP + 拦截器

相关推荐
蓝斯4973 小时前
[原创]《C#高级GDI+实战:从零开发一个流程图》第章:增加贝塞尔曲线,上、下、左、右连接点
java·c#·流程图
前端工作日常4 小时前
我学习到的Java 的 Service 分层:itf 和 impl 到底是什么?
java·后端
都叫我大帅哥4 小时前
Spring @Transactional 注解完全指南
java·spring
Java成神之路-4 小时前
G1 垃圾回收器 :SATB + TAMS核心机制深度解析
java·jvm
前端工作日常5 小时前
我学习到的JIT即时编译与机器码缓存失效
java·后端
带刺的坐椅5 小时前
Solon 的 10 种 HTTP 服务器:改一行依赖,换一个引擎
java·solon·jetty·undertow·mcp-server·htttp
xcLeigh6 小时前
Go入门:变量声明的五种方式详解
java·开发语言·golang
AI大模型-小华6 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
Mark_ZP6 小时前
【锁1】Synchronized vs ReentrantLock区别
java
立心者07 小时前
SpringBoot中使用TOTP实现MFA(多因素认证)
java·spring boot·后端