2014-12-01 6 views
2


Привет, каждый.
Я хочу, чтобы добавить слушателя на вызываемый метод по телефону, как это:Слушатель на Method.invoke java

myClass.myMethod(...); 

Во время выполнения, это будет что-то вроде:

listenerClass.beforeMethod(...); 
myClass.myMethod(...); 
listenerClass.beforeMethod(...); 

Я хотел, чтобы переопределить Method.invoke(...):

public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { 
    doBefore(...); 
    super.invoke(...); 
    doAfter(...); 
} 

Class.java и Method.java являются окончательными, и я попробовал использовать свой собственный ClassLoader. Возможно, фабрика или аннотация могут выполнять работу. Спасибо за ваш ответ.

+0

Пожалуйста, найдите минутку и прочитайте Справочный центр о том, как отформатировать сообщение. –

ответ

7

Одним из вариантов является использование ориентированных на ASP шаблонов программирования.

В этом случае вы можете использовать прокси (JDK или CGLIB).

Вот пример с проксими JDK. Вам нужно интерфейс

interface MyInterface { 
    public void myMethod(); 
} 

class MyClass implements MyInterface { 
    public void myMethod() { 
     System.out.println("myMethod"); 
    } 
} 

... 

public static void main(String[] args) throws Exception { 
    MyClass myClass = new MyClass(); 
    MyInterface instance = (MyInterface) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), 
      new Class<?>[] { MyInterface.class }, new InvocationHandler() { 
       MyClass target = myClass; 

       @Override 
       public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
        if (method.getName().equals("myMethod")) { // or some other logic 
         System.out.println("before"); 
         Object returnValue = method.invoke(target, args); 
         System.out.println("after"); 
         return returnValue; 
        } 
        return method.invoke(target); 
       } 
      }); 
    instance.myMethod(); 
} 

отпечатки

before 
myMethod 
after 

Очевидно, что есть библиотеки, которые делают это гораздо лучше, чем выше. Взгляните на Spring AOP и AspectJ.

+1

Другим способом является использование инъекции байт-кода с библиотекой, такой как [ASM] (http://asm.ow2.org) или [Javassist] (http://www.csg.ci.iu-tokyo.ac.jp/~ chiba/javassist) – Lolo

+0

@Lolo отличные ссылки, спасибо за обмен. Вы знаете похожие библиотеки для C/C++? – ALTN

Смежные вопросы