在代理invoke方法中调用被代理对象方法是否可行?
关于动态代理invoke方法中调用被代理对象getId()的可行性解答
首先明确说:这完全可行,但要注意避开一个常见的递归陷阱。
我来给你拆解清楚:
- 你的
ClientContainerInvocationHandler持有的是被代理的真实SocketContainer对象(我们一般叫它target),当你在invoke方法里直接调用target.getId()时,这是直接调用真实对象的原生方法,不会触发代理的invoke逻辑——相当于绕开了代理,直接和真实对象交互,所以完全安全,不会有任何问题。 - 但如果你不小心写成调用代理对象(也就是
invoke方法的第一个参数proxy)的getId(),比如((IClient)proxy).getId(),那麻烦就来了:调用代理对象的方法会再次触发invoke方法,这样就会无限递归调用invoke,直到栈溢出抛出StackOverflowError。
给你举个正确的代码示例参考:
public class ClientContainerInvocationHandler implements InvocationHandler { // 持有被代理的真实对象 private final IClient target; public ClientContainerInvocationHandler(IClient target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 正确调用:直接访问真实对象的getId(),不会触发代理 int clientId = target.getId(); System.out.println("当前处理的客户端ID:" + clientId); // 执行原本的方法调用(如果需要的话) return method.invoke(target, args); } }
简单来说:只要你调用的是真实被代理对象的方法,就没问题;别去调用代理对象的同名方法就行。
内容的提问来源于stack exchange,提问作者Joel
相关产品推荐
相关产品推荐

