Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

It seems reflection.proxy does not what is expected when there are overriden methods. In detail, starting with simple application:

static void debug( String fmt, Object... args ) {
    System.out.println( String.format(fmt,args));
}

interface I {
    void m1();
    void m2();
}

static class A implements I {
    public void m1() { System.out.println( "A.m1" ); m2(); }
    public void m2() { System.out.println( "A.m2" ); }
}

static class B extends A {
    @Override
    public void m2() { System.out.println( "B.m2" ); }
}


public static void main( String[] args )
{
    B b = new B();
    b.m1();
}

the output is, as expected:

A.m1
B.m2

Now, we try to proxify the calls to all methods of "B b". Following new code is added:

static public class HelloInvocationHandler implements InvocationHandler {

    I proxied;

    HelloInvocationHandler( I proxied ) {
        this.proxied = proxied;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {

        String methodName = method.getName();
        debug( "HelloInvocationHandler: invoke method %s", methodName);
        return method.invoke(proxied,args);
    }
}

public static void main( String[] args )
{
    B b = new B();
    HelloInvocationHandler handler = new HelloInvocationHandler(b);
    I pb = (I) Proxy.newProxyInstance(
            I.class.getClassLoader(),
            new Class[] { I.class },
            handler);

    pb.m1();
}

and the new output is:

HelloInvocationHandler: invoke method m1
A.m1
B.m2

as you can see, the call to "m2" is not executed accross the proxy. If all call to B's methods was accross the proxy, a line "HelloInvocationHandler: invoke method m2" should appear in the ouput.

Any hint?

Thanks.

See Question&Answers more detail:os

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

1 Answer

You can use CGLib library to create proxy. Use Enhancer.create(B.class, new HelloInvocationHandler()) to to intercept method invocations. It's not harder than using JDK Proxy, but much more flexible. Should help in your case. The interceptor should be implemented like this:

public class HelloInvocationHandler implements MethodInterceptor {

    public Object intercept(Object object, Method method, Object[] args,
         MethodProxy methodProxy) throws Throwable {
     debug( "HelloInvocationHandler: invoke method %s", method.getName());
     return methodProxy.invokeSuper(object, args);
    }
}

Use it like this:

B pb = (B)Enhancer.create(B.class, new HelloInvocationHandler());
pb.m1();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...