在 Java 中,Proxy(动态代理)失效是一个常见问题,通常不是 Proxy 本身有 bug,而是使用方式或场景不满足动态代理的前提条件。下面按最常见原因 → 原理 → 解决办法来说明。
| 场景 | 是否支持 Proxy | 原因 |
|---|---|---|
| 代理 接口 | ✅ | JDK 动态代理只能代理接口 |
| 代理 普通类(非接口) | ❌ | JDK Proxy 不支持 |
| 调用 this 方法 | ❌ | 不会走代理 |
| 方法是 final / static / private | ❌ | 无法被代理 |
| 方法是 Object 的基础方法(如 getClass) | ❌ | 不走代理逻辑 |
| 代理对象未生效(直接用 new) | ❌ | 没用 Proxy 返回的对象 |
| Spring AOP 同类方法调用 | ❌ | 本质是 this 调用 |
interface Service {
void hello();
}
class ServiceImpl implements Service {
public void hello() {}
}
✅ 正确:
Service proxy = (Service) Proxy.newProxyInstance(
classLoader,
new Class[]{Service.class},
handler
);
❌ 错误(会直接失败):
Proxy.newProxyInstance(
classLoader,
new Class[]{ServiceImpl.class}, // 类不行
handler
);
如果你要代理类 → 用 CGLIB / ByteBuddy
public class ServiceImpl implements Service {
public void a() {
b(); // this.b()
}
public void b() {}
}
即使你代理了 Service:
proxy.a();
b() 不会走代理!
proxy.a() → 进入 InvocationHandlera() 内部调用的是 this.b()this 是 真实对象,不是代理对象AopContext.currentProxy()(Spring)((Service) AopContext.currentProxy()).b();
public final void test() {} // ❌
public static void test() {} // ❌
private void test() {} // ❌
这些方法是不能被重写 / 拦截的,Proxy 无能为力。
✅ 解决:改为 public 非 final 方法
这些方法 不会经过 InvocationHandler:
getClass()hashCode()(部分)equals()(部分)toString()(部分)❌ 错误:
ServiceImpl service = new ServiceImpl();
service.hello(); // 根本没用代理
✅ 正确:
Service proxy = createProxy();
proxy.hello();
@Service
public class UserService {
@Transactional
public void a() {
b();
}
@Transactional
public void b() {}
}
→ b() 的事务不生效
@Async
private void task() {} // ❌
@EnableAspectJAutoProxySystem.out.println(proxy instanceof Proxy); // true
或打印:
proxy.getClass().getName();
// com.sun.proxy.$Proxy12
✅ 以下情况:
proxyTargetClass=true)@EnableAspectJAutoProxy(proxyTargetClass = true)
Java Proxy 失效,90% 是因为:
- 代理了类而不是接口
- 用了 this 调用
- 方法是 final / private / static
如果你愿意,可以把**具体代码或框架(Spring / MyBatis / 自定义 Proxy)**贴出来,我可以直接帮你定位是哪一条原因。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。