@Test public void shouldProxyAnonymousClass() throws Exception { Runnable runnable = new Runnable() { @Override public void run() { throw new UnsupportedOperationException(); } }; @SuppressWarnings("unchecked") Class<Runnable> type = (Class<Runnable>) runnable.getClass(); new InvocationProxy<Runnable>(type) { @Override public Object invoke(Method method, Object... args) { methodCalled = method; argsCalled = args; return null; } }.newInstance().run(); assertEquals("run", methodCalled.getName()); assertEquals(0, argsCalled.length); }
public T newInstance() { String className = targetType.getName() + "$$InvocationProxy"; try { Class<T> type = proxyType(className); log.debug("instantiate {}", type); Constructor<T> constructor = type.getConstructor(InvocationProxy.class); return constructor.newInstance(this); } catch (Exception e) { throw new RuntimeException("can't generate " + className, e); } }
InvocationProxy { public T newInstance() { String className = targetType.getName() + "$$InvocationProxy"; try { Class<T> type = proxyType(className); log.debug("instantiate {}", type); Constructor<T> constructor = type.getConstructor(InvocationProxy.class); return constructor.newInstance(this); } catch (Exception e) { throw new RuntimeException("can't generate " + className, e); } } }
InvocationProxy { public T newInstance() { String className = targetType.getName() + "$$InvocationProxy"; try { Class<T> type = proxyType(className); log.debug("instantiate {}", type); Constructor<T> constructor = type.getConstructor(InvocationProxy.class); return constructor.newInstance(this); } catch (Exception e) { throw new RuntimeException("can't generate " + className, e); } } InvocationProxy(Class<T> targetType); }
InvocationProxy { public T newInstance() { String className = targetType.getName() + "$$InvocationProxy"; try { Class<T> type = proxyType(className); log.debug("instantiate {}", type); Constructor<T> constructor = type.getConstructor(InvocationProxy.class); return constructor.newInstance(this); } catch (Exception e) { throw new RuntimeException("can't generate " + className, e); } } InvocationProxy(Class<T> targetType); T newInstance(); abstract Object invoke(Method method, Object... args); }
InvocationProxy { public T newInstance() { String className = targetType.getName() + "$$InvocationProxy"; try { Class<T> type = proxyType(className); log.debug("instantiate {}", type); Constructor<T> constructor = type.getConstructor(InvocationProxy.class); return constructor.newInstance(this); } catch (Exception e) { throw new RuntimeException("can't generate " + className, e); } } InvocationProxy(Class<T> targetType); T newInstance(); abstract Object invoke(Method method, Object... args);  }