Java动态调用在对象上动态附加(通过动态代理)的方法

时间:2016-04-06 10:49:56

标签: java reflection proxy invoke dynamic-proxy

我有一个方法,它有一个参数实例和一个表示方法名称的字符串,具有以下签名:

Object executeDynamicMethod(Object instance, String methodName);

我可以通过使用反射按名称轻松执行方法,如下所示:

Method methodToExecute = instance.getClass().getMethod(methodName...);
methodToExecute.invoke(); ...

但是,当实例是代理实例时,会发生什么情况,并且该方法是通过调用处理程序运行的?那么实例对象类在这里没有方法,我无法得到它并调用它。 另外,我不想使用 Proxy.getInvocationHandler(instance),因为有时候实例是代理的,但有时候不是,我不想用来破坏它如果陈述。

因此,有没有办法在实例上通过名称调用方法而不必先从类中检索方法? 感谢。

2 个答案:

答案 0 :(得分:0)

  

当实例是代理实例时会发生什么,并且该方法是通过调用处理程序运行的?

没有区别。代理必须实施interface

中的所有方法
  

然后这里的实例对象Class没有方法,我无法得到它并调用它。

InvocationHandler可以,但代理会这样做。代理使用它实现的接口调用处理程序。

  

有没有办法在实例上按名称调用方法而不必先从类中检索方法?

你不应该以不同的方式尝试代理。

答案 1 :(得分:0)

我有类似的问题。在我的情况下,我实现了委托给“真实”对象的代理(出于缓存原因)。但有时代表也是代理人。但是,在此代理中,有时必须通过对类的反射以及有时在代理上调用方法(如您的问题)。 我希望这个小例子不言自明。

public class ProxyTest {

interface A {
    public void doit();
}

static class B implements A {
    @Override
    public void doit() {
        System.out.println("I am a B");
    }
}

static class ProxyOfA implements InvocationHandler {
    private A delegate;

    ProxyOfA(A delegate) {
        this.delegate = delegate;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (delegate instanceof Proxy) {
            //This is a proxy
            InvocationHandler invocationHandler = Proxy.getInvocationHandler(delegate);
            invocationHandler.invoke(delegate, method, args);
        } else {
            // This is not a proxy
            method.invoke(delegate, args);
        }
        System.out.println("Proxy of Proxy invoked");
        return null;
    }

}

public static void main(String[] args) {
    //instantiate targets
    A b = new B();
    A proxy = (A) Proxy.newProxyInstance(A.class.getClassLoader(), new Class[] { A.class },
            new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("I am a Proxy");
                    return null;
                }
            });

    //instantiate proxies
    A proxyOfb = (A) Proxy.newProxyInstance(A.class.getClassLoader(), new Class[] { A.class }, new ProxyOfA(b));
    A proxyOfproxy = (A) Proxy.newProxyInstance(A.class.getClassLoader(), new Class[] { A.class }, new ProxyOfA(proxy));

    //invoke
    proxyOfb.doit();
    proxyOfproxy.doit();
}
}

这将打印

I am a B
Proxy of Proxy invoked
I am a Proxy
Proxy of Proxy invoked