spring aop底层的代理实现方式是什么

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)。