import java.lang.reflect.Method; import java.lang.Class; import java.lang.reflect.Proxy; import java.util.*; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; interface I{ public void hello(); } class A implements I{ public void hello(){ System.out.println("hello"); } } interface B{ public void call_hello(I i); public void foo(); } class BImpl implements B{ public void call_hello(I i){ i.hello(); } public void foo(){ System.out.println("foo"); } } class BProxy implements InvocationHandler { private B first; private B second; Set send_to_first = new HashSet(Arrays.asList(new String[]{ "foo","bar"})); Set send_to_second = new HashSet(Arrays.asList(new String[]{ "zork","foobar"})); Set send_to_both = new HashSet(Arrays.asList(new String[]{ "something"})); public static Object newInstance(B b) { return java.lang.reflect.Proxy.newProxyInstance( B.class.getClassLoader(), new Class[] { B.class }, new BProxy(b)); } public BProxy(B b) { this.first = b; this.second = new BImpl(); } public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { Object result; try { String methodName = m.getName(); if (send_to_first.contains(methodName)){ return m.invoke(first, args); } else if (send_to_second.contains(methodName)){ return m.invoke(second, args); } else { return m.invoke(this, args); } } catch (InvocationTargetException e) { throw e.getTargetException(); }// catch (Exception e) { // throw new RuntimeException("unexpected invocation exception: " + // e.getMessage()); //} } } public class testCase{ public static void main(String[] args) { try{ B b = new BImpl(); A a = new A(); b.call_hello(a); B proxy = (B) BProxy.newInstance(b); proxy.foo(); proxy.call_hello(a); } catch (Exception e){ e.printStackTrace(); } } }