2016-04-06 5 views
2

У меня есть метод, который имеет аргументы экземпляр объекта и строку, которая представляет собой имя методы, со следующей подписью:Java динамически вызывать метод, который динамически прикрепленный (с помощью динамического прокси) на объекте

Object executeDynamicMethod(Object instance, String methodName); 

можно легко выполнить метод по имени с помощью отражения, что-то вроде следующего:

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

Однако то, что происходит, когда экземпляр проксированном один, и метод работает, хотя обработчик вызова? Тогда объект Объект класса здесь не имеет метода, и я не могу его получить и вызвать. Кроме того, я не хочу использовать Proxy.getInvocationHandler (экземпляр), потому что иногда экземпляр проксирован, но иногда нет, и я не хочу его испортить , если операторов.

Таким образом, существует ли способ вызвать метод по его имени в экземпляре без необходимости сначала извлекать метод из класса? Спасибо.

ответ

0

Что происходит, когда экземпляр является прокси-сервером, а метод работает с помощью обработчика вызова?

Нет никакой разницы. Прокси-сервер должен реализовать все методы в вашем interface

Затем объект класса экземпляра здесь не имеет метод, и я не могу получить его и ссылаться на него.

InvocationHandler делает, но прокси-сервер делает. Прокси вызывает обработчик с помощью метода из интерфейса, который он реализует.

Есть ли способ вызвать метод по его имени в экземпляре без необходимости сначала получить метод из класса?

Вам не нужно пробовать прокси (-ы) по-другому.

+0

Право это действительно работает, спасибо! –

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