/** * This implementation is variation from {@link #tee(Class, Object...)}, read that documentation * first. * <p> * The behavior modifies from that implementation is that all instances will be called by a * executor. This means that invocations into the returned instance will return immediately, * but instance invocation will happen async. It is guaranteed that any single instance will NOT * be invoked in parallel. Thus meaning that if you invoke into the proxy two times before * a give instance finishes processing the first invocation, the second invocation will queue and * only be invoked after the first finishes. * <p> * Under the hood {@link DefaultExecutorListenerHelper} is used to provide this behavior. * * @param <T> Type representing interface to multiple invocations of * @param executor Executor that instances will be invoked on to * @param teeInterface Interface class for which the returned instance must implement * @param instances Instances of said interface which invocations should be multiplied to * @return A returned interface which will map all invocations to all provided interfaces */ public static <T> T teeWithExecutor(Executor executor, Class<? super T> teeInterface, T ... instances) { return setupHelper(new DefaultExecutorListenerHelper<>(teeInterface, executor), instances); }
/** * This implementation is variation from {@link #tee(Class, Object...)}, read that documentation * first. * <p> * The behavior modifies from that implementation is that all instances will be called by a * executor. This means that invocations into the returned instance will return immediately, * but instance invocation will happen async. It is guaranteed that any single instance will NOT * be invoked in parallel. Thus meaning that if you invoke into the proxy two times before * a give instance finishes processing the first invocation, the second invocation will queue and * only be invoked after the first finishes. * <p> * Under the hood {@link DefaultExecutorListenerHelper} is used to provide this behavior. * * @param <T> Type representing interface to multiple invocations of * @param executor Executor that instances will be invoked on to * @param teeInterface Interface class for which the returned instance must implement * @param instances Instances of said interface which invocations should be multiplied to * @return A returned interface which will map all invocations to all provided interfaces */ public static <T> T teeWithExecutor(Executor executor, Class<? super T> teeInterface, T ... instances) { return setupHelper(new DefaultExecutorListenerHelper<>(teeInterface, executor), instances); }
@Override protected <T> ListenerHelper<T> makeListenerHelper(Class<T> listenerInterface) { return new DefaultExecutorListenerHelper<>(listenerInterface, SameThreadSubmitterExecutor.instance()); }
@Test @Override @SuppressWarnings({ "unused", "unchecked", "rawtypes" }) public void constructorFail() { try { new DefaultExecutorListenerHelper(null, SameThreadSubmitterExecutor.instance()); fail("Exception should have thrown"); } catch (IllegalArgumentException e) { // expected } try { new DefaultExecutorListenerHelper(ArrayList.class, SameThreadSubmitterExecutor.instance()); fail("Exception should have thrown"); } catch (IllegalArgumentException e) { // expected } try { new DefaultExecutorListenerHelper(TestInterface.class, null); fail("Exception should have thrown"); } catch (IllegalArgumentException e) { // expected } } }