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