7

I have a question relating to dynamic proxies in java.

Suppose I have an interface called Foo with a method execute and class FooImpl implements Foo.

When I create a proxy for Foo and I have something like:

Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                     new Class[] { Foo.class },
                                     handler);

Suppose my invocation handler looks like:

public class FooHandler implements InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args) {
        ...
    }
}

If my invocation code looks something like

Foo proxyFoo = (Foo) Proxy.newInstance(Foo.getClass().getClassLoader(),
                                       new Class[] { Foo.class },
                                       new FooHandler());
proxyFoo.execute();

If the proxy can intercept the aforementioned call execute from the Foo interface, where does the FooImpl come in to play? Maybe I am looking at dynamic proxies in the wrong way. What I want is to be able to catch the execute call from a concrete implementation of Foo, such as FooImpl. Can this be done?

Many thanks

2 Answers 2

3

The way to intercept methods using dynamic proxies are by:

public class FooHandler implements InvocationHandler {
    private Object realObject;

    public FooHandler (Object real) {
        realObject=real;
    }


    public Object invoke(Object target, Method method, Object[] arguments) throws Throwable {
        if ("execute".equals(method.getName()) {
            // intercept method named "execute"
        }

        // invoke the original methods
        return method.invoke(realObject, arguments);
    }
}

Invoke the proxy by:

Foo foo = (Foo) Proxy.newProxyInstance(
            Foo.class.getClassLoader(),
            new Class[] {Foo.class}, 
            new FooHandler(new FooImpl()));
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks guys. So an invocation of my code would look like: Foo f = new FooImpl(); FooHandler fh = new FooHandler(f); correct?
@Johan: I'm sure you didn't mean to write new Foo() there, as first of all Foo is an interface. I think that should be new FooHandler(new FooImpl()).
Guys, just one last thing - Why does the 'Foo.class.getClassLoader()' need to be passed in as an argument to the newProxyInstance method? What exactly does that do? Thanks
@Joeblackdev, In environments when using e.g., multiple jar-files they will each provide their own classloader and it might be desirable to select which to use.
@Joeblackdev: A class is only "equal to itself" in the same class loader. If Foo is loaded in some other CL it will be a different class. So you want to make sure that the returned Foo does not come from some other class loader, or otherwise you'll get a ClassCastException. The Proxy doesn't want to rely on the context classloader of the current thread as that's not guaranteed to be the one you expect.
2

If you want to delegate to some Foo implementation like FooImpl, just make your InvocationHandler a wrapper of an other Foo instance (passed to the constructor) and then send a FooImpl instance as the delegate. Then, inside the handler.invoke() method, call method.invoke(delegate, args).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.