NonDataOperationInvocationHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) { log.info("Intercepting non-data method " + method); for (NonDataOperationHandler handler : handlers) { if (handler.handles(proxy, method, args)) { log.info("Found handler " + handler + " for method " + method); return handler.invoke(proxy, args); } } log.error("No data or non-data operation handler could be found for method " + method); throw new UnknownDataOperationException(method); } NonDataOperationInvocationHandler();  NonDataOperationInvocationHandler(boolean registerDefaults); @Override Object invoke(Object proxy, Method method, Object[] args); void register(NonDataOperationHandler handler); List<NonDataOperationHandler> getHandlers();  }
@Test public void testHandlingKnownMethods() throws Throwable { final NonDataOperationInvocationHandler handler = new NonDataOperationInvocationHandler(); final Object proxy = new Object(); assertThat(handler.invoke(proxy, Object.class.getMethod("hashCode"), new Object[]{}), Matchers.is(proxy.hashCode())); assertThat(handler.invoke(proxy, Object.class.getMethod("toString"), new Object[]{}), Matchers.is(proxy.toString())); assertThat(handler.invoke(proxy, Object.class.getMethod("equals", Object.class), new Object[]{proxy}), Matchers.is(true)); assertThat(handler.invoke(proxy, Object.class.getMethod("equals", Object.class), new Object[]{new Object()}), Matchers.is(false)); }
@Test(expectedExceptions = UnknownDataOperationException.class) public void testUnknownMethod() throws Throwable { final NonDataOperationInvocationHandler handler = new NonDataOperationInvocationHandler(); handler.invoke(new Object(), Object.class.getMethod("wait"), new Object[]{}); }