为什么InvocationHandler中的方法invoke()有一个参数Object proxy?

时间:2010-12-20 12:37:27

标签: java dynamic proxy invoke

当你检查方法调用(Object proxy,Method method,Object [] args)声明&在doc语句中,您会发现输入参数代理

  

proxy - 在

上调用该方法的代理实例

当我在java动态代理上进行测试时,我发现这个代理是由vm生成的。所以我想知道为什么方法调用有这个参数,除了那只是一个对象($ proxy0) )但我们的使用没有实际行动?

3 个答案:

答案 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 类来处理多个代理接口。