I want to create a dynamic proxy that can delegate its methods to different implementations (each method call selects a potentially different object). And I want to achieve a polymorphic effect, for example, when a proxied method calls another proxied method, the object selection mechanism is applied again.
Ok, enough confusion, here is an example:
interface IService { void a(); void b(); } class HappyService implements IService { public void a() { System.out.println("Happy a"); b(); } public void b() { System.out.println("Happy b"); } } class SadService implements IService { public void a() { System.out.println("Sad a"); b(); } public void b() { System.out.println("Sad b"); } }
Now I want to create a proxy for IService , which always selects HappyService for invocations of a() method and SadService for calls to b() method. Here's what comes to my mind:
InvocationHandler h = new InvocationHandler() { @Override public Object invoke( final Object proxy, final Method method, final Object[] args ) throws Throwable { Object impl; if (method.getName().equals("a")) { impl = new HappyService(); } else if (method.getName().equals("b")) { impl = new SadService(); } else { throw new IllegalArgumentException("Unsupported method: " + method.getName()); } return method.invoke(impl, args); } }; IService service = (IService)Proxy.newProxyInstance( IService.class.getClassLoader(), new Class[]{ IService.class }, h ); service.a();
Fingerprints:
Happy a Happy b
Yes, this is because calling b() inside a() knows nothing about dynamic proxies.
So how do I best achieve my goal? My desired result:
Happy a Sad b
I could replace my new HappyService() inside the call handler with another proxy, which only passes the a() method to HappyService and redirects all the other methods back to the original proxy. But maybe there is a better / simpler solution?
source share