当你检查方法调用(Object proxy,Method method,Object [] args)声明&在doc语句中,您会发现输入参数代理
proxy - 在
上调用该方法的代理实例
当我在java动态代理上进行测试时,我发现这个代理是由vm生成的。所以我想知道为什么方法调用有这个参数,除了那只是一个对象($ proxy0) )但我们的使用没有实际行动?
答案 0 :(得分:4)
如果您有多个代理对象的单个调用句柄,这非常有用。因此,您可以使用哈希映射来存储代理状态信息。例如 - Mokito测试框架存储代理调用历史。
答案 1 :(得分:0)
如果您是中国人,可以阅读这篇文章http://rejoy.iteye.com/blog/1627405
他对$ proxy0.class进行了分解,你应该知道$ proxy0扩展代理
public final class $Proxy0 extends Proxy
implements UserService
并且$ proxy0中有一个函数:
public final void add()
{
try
{
//the h(invocationhandler) is in Proxy class,so we need pass this $proxy0 instance to super ,so the super(Proxy) can invoke($proxy0,method,args)
super.h.invoke(this, m3, null);
return;
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
答案 2 :(得分:0)
我们可以使用
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
生成 $proxy.class
文件。
反编译.class
文件,我们会发现这个类每个java方法(除了native方法)都被InvocationHandler调用
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
super.h
对象是 InvocationHandler 实例。
在 System.out.println(proxy)
中使用 invocationHandler.invoke
会导致无限递归和 StackOverflowException。
所以我认为关于代理参数的唯一功能是使用 getClass()
方法
获取 GeneratedProxy.class
信息,例如实现了哪些接口。
在InvocationHandler的invoke方法实现中,我们可以知道代理对象的类型
因此我们可以使用单个 InvocationHander 类来处理多个代理接口。