Spring AOP 的代理实现方式,本质上只有两条路:
JDK 动态代理
CGLIB(基于 ASM 的字节码增强)
Spring 没有第三条路。
你看到的所有 @Transactional、@Async、@Cacheable、@Secured、@Aspect,最终都落到这两个机制之一。
⸻
一、Spring AOP 的整体架构
Spring AOP 是一个**运行期织入(Runtime Weaving)**系统,工作流是:
Bean 创建
↓
AbstractAutoProxyCreator
↓
判断该 Bean 是否匹配 Advisor
↓
如果匹配 → 用代理对象替换原 Bean
你注入的:
@Autowired
UserService userService;
拿到的其实是:
JDK Proxy 或 CGLIB Proxy
⸻
二、Spring 什么时候用 JDK 动态代理?
条件只有一个:
这个 Bean 至少实现了一个接口
例如:
public interface UserService {
void create();
}
@Service
public class UserServiceImpl implements UserService {
}
Spring 默认会生成:
$Proxy42 extends Proxy implements UserService
底层是:
java.lang.reflect.Proxy
调用路径:
Controller
-> $Proxy42.create()
-> InvocationHandler.invoke()
-> MethodInterceptor链
-> 目标方法
优点
• 生成快
• 内存小
• JDK 原生支持
缺点
• 只能代理接口
• 无法代理类方法
⸻
三、什么时候用 CGLIB?
如果满足任一条件:
1. 没有接口
2. 配置了
spring.aop.proxy-target-class=true
3. 使用 @Transactional + Kotlin / record / final 类
就会使用 CGLIB。
生成的是:
UserService$$SpringCGLIB$$0
extends UserService
它是子类代理。
底层过程:
ASM 生成子类字节码
→ 覆写所有非 final 方法
→ 插入拦截器回调
调用路径:
userService.create()
↓
UserService$$CGLIB.create()
↓
MethodInterceptor.intercept()
↓
Advice 链
↓
super.create()
⸻
四、Spring AOP 的真正核心:Interceptor Chain
无论是 JDK Proxy 还是 CGLIB,最终都会进入:
org.springframework.aop.framework.ReflectiveMethodInvocation
它内部是一个链:
[TransactionInterceptor]
[SecurityInterceptor]
[CacheInterceptor]
[AspectJMethodInterceptor]
↓
target method
这是责任链模式。
所有 AOP 功能都是拦截器堆出来的,而不是魔法。
⸻
五、为什么 Spring Boot 4 + Loom 对 AOP 没影响?
你之前问了虚拟线程 + Security,这里刚好呼应:
Spring AOP 依赖的是:
调用栈 + ThreadLocal
而虚拟线程是:
完整栈 + 独立 ThreadLocal
所以:
• @Transactional 的事务同步
• @Secured 的 SecurityContext
• @Async 的拦截切换
都在 同一个虚拟线程调用栈 里完成
代理对象根本不知道它运行在 carrier thread 还是 virtual thread。
⸻
六、一个资深工程师最该知道的坑
1️⃣ final 方法永远不能被 AOP
CGLIB 是继承:
final void pay() {} // 无法覆写 → 无法拦截
Spring 会悄悄放过你,不报错。
⸻
2️⃣ self-invocation 失效
class OrderService {
@Transactional
public void save() {}
public void create() {
save(); // 不经过代理
}
}
调用路径:
this.save() → 直接调原方法 → AOP失效
⸻
3️⃣ JDK Proxy 类型擦除坑
@Autowired
UserServiceImpl impl; // ❌ JDK Proxy 不能注入实现类
只能:
@Autowired
UserService service; // ✅
⸻
七、一句话总结
Spring AOP = JDK Proxy(接口) + CGLIB(类) + Interceptor Chain(真正逻辑)
它不是魔法,而是:
代理模式 + 责任链 + 反射 / 字节码增强的工程化实现。
如果你愿意,我可以下一步给你画一张
@Transactional 从调用到提交的完整调用链(代理 → 拦截器 → DataSource → JDBC)。