Spring AOP默认使用JDK动态代理(目标类实现接口时),否则回退CGLIB;代理由容器管理以支持生命周期、通知织入和切面协同,手动创建无法接入AOP基础设施。

Spring AOP 默认使用 Java 动态代理实现切面逻辑,前提是目标类实现了接口;此时 Spring 会基于 java.lang.reflect.Proxy 创建代理对象,将通知(Advice)织入方法调用过程。
代理创建的触发条件
Spring 容器在创建 Bean 时,如果该 Bean 被某个切面(@Aspect)匹配到,并且满足以下任一条件,就会为其生成代理:
- 目标类实现了至少一个接口 → 使用 JDK 动态代理(默认)
- 配置了
proxy-target-class=true或使用@EnableAspectJAutoProxy(proxyTargetClass = true)→ 强制使用 CGLIB 代理(即使有接口) - 目标类没有实现接口但启用了 CGLIB(默认开启)→ 自动回退到 CGLIB 代理
动态代理的核心流程
以 JDK 动态代理为例,Spring AOP 实际上封装了标准流程:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 定义
InvocationHandler实现类(Spring 内部是ReflectiveMethodInvocation及其委托链) - 在 handler 的
invoke()中,按顺序执行:前置通知 → 目标方法 → 后置/返回/异常通知 - 通过
Proxy.newProxyInstance()创建代理实例,该实例实现了目标类的所有接口 - 外部代码注入或获取的 Bean,实际是这个代理对象,而非原始实例
为什么不能直接 new 代理对象?
Spring AOP 的代理由容器统一管理,关键原因包括:
立即学习“Java免费学习笔记(深入)”;
- 代理对象需要与 IoC 容器生命周期同步(如依赖注入、初始化回调、销毁逻辑)
- 通知的解析(@Before/@Around 等)、切点表达式(pointcut)匹配、增强排序都依赖 Spring 的
Advised接口和Advisor体系 - 手动调用
Proxy.newProxyInstance()无法接入 Spring 的 AOP 基础设施(比如事务、缓存等其他切面)
验证代理是否生效的小技巧
在运行时检查 Bean 类型,可快速确认是否被代理:
Object bean = applicationContext.getBean("userService");
System.out.println(bean.getClass()); // 输出类似:com.sun.proxy.$Proxy45 或 UserService$$EnhancerBySpringCGLIB$$a1b2c3d4
System.out.println(AopUtils.isAopProxy(bean)); // true
System.out.println(AopUtils.isJdkDynamicProxy(bean)); // true(JDK 代理时)
System.out.println(AopUtils.isCglibProxy(bean)); // true(CGLIB 代理时)

















