在 Java 中,JDK 动态代理(java.lang.reflect.Proxy) 和 CGLIB 代理 都是实现“运行时动态生成代理对象”的技术,常用于 AOP、事务、日志等场景。它们的核心区别如下:
| 对比项 | JDK Proxy(Java 原生) | CGLIB |
|---|---|---|
| 作者 | JDK 自带 | 第三方(基于 ASM) |
| 代理方式 | 基于接口 | 基于继承(子类) |
| 是否依赖接口 | ✅ 必须 | ❌ 不需要 |
| 生成代理原理 | 实现接口 + 反射调用 | 继承目标类 + 字节码增强 |
| 性能(早期) | 较慢 | 较快 |
| 性能(现代 JDK) | 接近甚至更好 | 仍快但差距变小 |
| 对 final 支持 | 接口无 final 问题 | ❌ 不能代理 final 类 / final 方法 |
public interface UserService {
void save();
}
UserService proxy = (UserService) Proxy.newProxyInstance(
clazz.getClassLoader(),
new Class[]{UserService.class},
(p, method, args) -> {
System.out.println("before");
Object result = method.invoke(target, args);
System.out.println("after");
return result;
}
);
final 类 / final 方法Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
System.out.println("before");
Object result = proxy.invokeSuper(obj, args);
System.out.println("after");
return result;
});
UserService proxy = (UserService) enhancer.create();
Spring AOP 默认策略:
@EnableAspectJAutoProxy(proxyTargetClass = true)
✅ 用 JDK Proxy:
✅ 用 CGLIB:
JDK Proxy 代理“接口”,CGLIB 代理“类”;
有接口用 JDK,没接口用 CGLIB。
如果你愿意,我也可以从 源码层面 或 性能测试对比 再深入讲。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。