在 Java 中使用 动态代理(Proxy) 或 CGLIB / ByteBuddy 等代理方式时,开发者经常会踩到一些坑。下面按常见错误类型 + 原因 + 示例/解决方式来说明。
错误表现:
new ProxyInstance(...) 时报 ClassCastException
原因:
JDK 动态代理 只能代理接口,不能代理普通类。
class UserService { } // ❌ 非接口
Proxy.newProxyInstance(
loader,
new Class[]{UserService.class}, // ❌
handler
);
✅ 正确方式:
interface UserService { }
class UserServiceImpl implements UserService { }
错误示例:
UserServiceimpl proxy = (UserServiceimpl) Proxy.newProxyInstance(...);
❌ 代理对象 不是原类类型
✅ 应该:
UserService proxy = (UserService) Proxy.newProxyInstance(...);
错误示例:
public Object invoke(Object proxy, Method method, Object[] args) {
return null; // ❌ 所有方法都返回 null
}
后果:
nullNullPointerException✅ 正确:
return method.invoke(target, args);
错误示例:
public Object invoke(Object proxy, Method method, Object[] args) {
proxy.toString(); // ❌ 无限递归
}
✅ 使用 target 对象:
target.toString();
问题: 这些方法也会被代理拦截,可能导致:
✅ 建议特殊处理:
if (method.getName().equals("toString")) {
return target.toString();
}
final class UserService { } // ❌
CGLIB 通过 继承 实现代理,final 类无法代理。
✅ 去掉 final
public final void save() { }
private void log() { }
❌ 这些方法 不会走代理逻辑
现象:
原因: CGLIB 创建代理对象时会调用父类构造方法
✅ 避免在构造方法中做复杂逻辑
@Service
public class UserService {
public void a() {
b(); // ❌ 不走 AOP
}
@Transactional
public void b() {}
}
✅ 解决方式:
AopContext.currentProxy()UserServiceImpl impl = (UserServiceImpl) springBean;
❌ Spring 默认使用 JDK 动态代理(接口)
✅ 配置 CGLIB:
spring:
aop:
proxy-target-class: true
✅ 只在必要层使用(Service / DAO)
多个 AOP + 自定义 Proxy 嵌套,导致:
| 类型 | 常见错误 |
|---|---|
| JDK Proxy | 非接口、强转错误 |
| InvocationHandler | 忘记 invoke、递归 |
| CGLIB | final 类/方法 |
| Spring AOP | 自调用无效 |
| 设计 | 代理滥用 |
如果你是想看 Spring AOP / MyBatis / RPC 框架中的 Proxy 错误,或者想看 真实报错堆栈分析,可以告诉我具体场景。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。