JavassistProxifier implements Proxifier { public <T> T proxify(Class<T> type, MethodInvocation<? super T> handler) { final ProxyFactory factory = new ProxyFactory(); factory.setFilter(IGNORE_BRIDGE_AND_OBJECT_METHODS); if (type.isInterface()) { factory.setInterfaces(new Class[] { type }); } else { factory.setSuperclass(type); } Class<?> proxyClass = factory.createClass(); Object proxyInstance = instanceCreator.instanceFor(proxyClass); setHandler(proxyInstance, handler); logger.debug("a proxy for {} is created as {}", type, proxyClass); return type.cast(proxyInstance); } JavassistProxifier(InstanceCreator instanceCreator); T proxify(Class<T> type, MethodInvocation<? super T> handler); boolean isProxy(Object o);  }
@Test public void shouldProxifyInterfaces() { TheInterface proxy = proxifier.proxify(TheInterface.class, new MethodInvocation<TheInterface>() { public Object intercept(TheInterface proxy, Method method, Object[] args, SuperMethod superMethod) { return true; } }); assertThat(proxy.wasCalled(), is(true)); }
@Test public void shouldProxifyConcreteClassesWithDefaultConstructors() { TheClass proxy = proxifier.proxify(TheClass.class, new MethodInvocation<TheClass>() { public Object intercept(TheClass proxy, Method method, Object[] args, SuperMethod superMethod) { return true; } }); assertThat(proxy.wasCalled(), is(true)); }
@Test public void shouldProxifyConcreteClassesWithComplexConstructorsAndPassNullForAllParameters() { TheClassWithComplexConstructor proxy = proxifier.proxify(TheClassWithComplexConstructor.class, new MethodInvocation<TheClassWithComplexConstructor>() { public Object intercept(TheClassWithComplexConstructor proxy, Method method, Object[] args, SuperMethod superMethod) { return superMethod.invoke(proxy, args); } }); assertThat(proxy.getFirstDependency(), is(nullValue())); assertThat(proxy.getSecondDependency(), is(nullValue())); }
@Test public void shouldNeverCallSuperclassConstructors() { TheClassWithManyConstructors proxy = proxifier.proxify(TheClassWithManyConstructors.class, new MethodInvocation<TheClassWithManyConstructors>() { public Object intercept(TheClassWithManyConstructors proxy, Method method, Object[] args, SuperMethod superMethod) { return superMethod.invoke(proxy, args); } }); assertThat(proxy.wasNumberConstructorCalled(), is(false)); assertThat(proxy.getNumber(), is(nullValue())); }
@Test public void shouldNotProxifyJavaLangObjectMethods() throws Exception { Object proxy = proxifier.proxify(JavassistProxifierTest.class, new MethodInvocation<Object>() { public Object intercept(Object proxy, Method method, Object[] args, SuperMethod superMethod) { fail("should not call this Method interceptor"); return null; } }); new Mirror().on(proxy).invoke().method("finalize").withoutArgs(); }
@Test public void shouldThrowProxyInvocationExceptionIfAnErrorOccurs() { C proxy = proxifier.proxify(C.class, new MethodInvocation<C>() { public Object intercept(C proxy, Method method, Object[] args, SuperMethod superMethod) { return superMethod.invoke(proxy, args); } }); try { proxy.doThrow(); fail("Should throw exception"); } catch (ProxyInvocationException e) { } }
@Test public void shouldNotProxifyBridges() throws Exception { B proxy = proxifier.proxify(B.class, new MethodInvocation<B>() { public Object intercept(B proxy, Method method, Object[] args, SuperMethod superMethod) { if (method.isBridge()) { fail("Method " + method + " is a bridge"); } return null; } }); Method[] methods = proxy.getClass().getMethods(); for (Method m : methods) { if (m.getName().equals("getT")) { m.invoke(proxy, ""); } } }