EventEmittingProxy implements InvocationHandler { public static <T> T proxying(Consumer<Event> eventConsumer, Class<? extends T> iface) { checkNotNull(eventConsumer, "eventConsumer must not be null"); return iface.cast(Proxy.newProxyInstance(iface.getClassLoader(), new Class<?>[] { iface }, new EventEmittingProxy<>(eventConsumer, EmitterInterfaceInfo.forInterface(iface).getEventMethodMapper()) )); } private  EventEmittingProxy(Consumer<Event> eventConsumer, EventMethodMapper eventMethodMapper); static T proxying(Consumer<Event> eventConsumer, Class<? extends T> iface); @Override Object invoke(Object proxy, Method method, Object[] args);  }
@Test public void emitsEventsBasedOnMethodCalls() { List<Event> emittedEvents = new ArrayList<>(); TestEvents emitter = EventEmittingProxy.proxying(emittedEvents::add, TestEvents.class); emitter.createdV2(StreamTimestamp.of("test", Instant.now()), UUID.randomUUID().toString(), "Arthur Putey", 41); emitter.nameUpdated(StreamTimestamp.of("test", Instant.now()), UUID.randomUUID().toString(), "Arthur Dent"); assertThat(emittedEvents.get(0).getParameters().toString(), equalTo("test/created_2{age=41, name=Arthur Putey}")); assertThat(emittedEvents.get(1).getParameters().toString(), equalTo("test/nameUpdated_0{updatedName=Arthur Dent}")); }