Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
936 views
in Technique[技术] by (71.8m points)

reflection - Listener on Method.invoke java


Hi, everyone.
I want to add a listener on an invoked method by calling like this :

myClass.myMethod(...);

In runtime, it will be something like :

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

I wanted to override Method.invoke(...) :

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

Class.java and Method.java are final and I tried with my own ClassLoader. Perhaps a factory or annotation can do the work. Thanks for your answer.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

One option is to use Aspect Oriented programming patterns.

In this case you can use a proxy (JDK or CGLIB).

Here's an example with JDK proxies. You'll need an interface

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();
}

prints

before
myMethod
after

Obviously, there are libraries that do this much better than the above. Take a look at Spring AOP and AspectJ.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...