【问题标题】:Java dynamically invoke method which is dynamically attached (by dynamic proxy) on an objectJava 动态调用方法,该方法动态附加(通过动态代理)在对象上
【发布时间】:2016-04-06 10:49:55
【问题描述】:

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

Object executeDynamicMethod(Object instance, String methodName);

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

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

但是,当实例是代理实例并且方法通过调用处理程序运行时会发生什么?那么这里的 instance 对象类没有方法,我无法获取并调用它。 另外,我不想使用 Proxy.getInvocationHandler(instance) 因为有时实例是代理的,但有时不是,我不想用 if破坏它> 声明。

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

【问题讨论】:

    标签: java reflection proxy invoke dynamic-proxy


    【解决方案1】:

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

    没有区别。代理必须实现interface中的所有方法

    那么这里的实例对象Class没有方法,无法获取调用。

    InvocationHandler 可以,但 Proxy 可以。代理使用它实现的接口中的方法调用处理程序。

    有没有什么方法可以在实例上通过方法名调用方法,而不必先从类中检索方法?

    您不必以任何不同的方式尝试代理。

    【讨论】:

      【解决方案2】:

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

      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();
      }
      }
      

      这将打印出来

      我是一个B 代理的代理被调用 我是代理 代理的代理被调用

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-04
        • 2021-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-18
        • 2016-01-20
        相关资源
        最近更新 更多