2014-12-01 115 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

請花點時間閱讀幫助中心,瞭解如何格式化您的帖子。 – 2014-12-01 16:54:53

回答

7

一種選擇是使用面向方面的編程模式。

在這種情況下,您可以使用代理(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/~千葉/ javassist) – Lolo 2014-12-01 17:12:26

+0

@Lolo優秀的鏈接,感謝分享。你知道C/C++的類似庫嗎? – ALTN 2017-06-29 14:38:52