Method.invoke java上的监听器

Ant*_*nt' 3 java reflection listener


嗨,大家好.
我想通过这样调用在调用的方法上添加一个监听器:

myClass.myMethod(...);
Run Code Online (Sandbox Code Playgroud)

在运行时,它将是这样的:

listenerClass.beforeMethod(...);
myClass.myMethod(...); 
listenerClass.beforeMethod(...);
Run Code Online (Sandbox Code Playgroud)

我想覆盖Method.invoke(...):

public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    doBefore(...);
    super.invoke(...);
    doAfter(...);
}
Run Code Online (Sandbox Code Playgroud)

Class.java和Method.java是final,我尝试使用自己的ClassLoader.也许工厂或注释可以完成这项工作.感谢您的回答.

Sot*_*lis 8

一种选择是使用面向方面的编程模式.

在这种情况下,您可以使用代理(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();
}
Run Code Online (Sandbox Code Playgroud)

版画

before
myMethod
after
Run Code Online (Sandbox Code Playgroud)

显然,有些库可以比上面做得更好.看看Spring AOP和AspectJ.

  • 另一种方法是使用字节码注入与[ASM](http://asm.ow2.org)或[Javassist](http://www.csg.ci.iu-tokyo.ac.jp/~chiba)等库/了Javassist) (2认同)