/* * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.aop.framework; import java.io.Serializable; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.junit.Test; import org.springframework.aop.interceptor.ExposeInvocationInterceptor; import org.springframework.aop.support.AopUtils; import org.springframework.tests.sample.beans.IOther; import org.springframework.tests.sample.beans.ITestBean; import org.springframework.tests.sample.beans.TestBean; import static org.junit.Assert.*; /** * @author Rod Johnson * @author Juergen Hoeller * @author Chris Beams * @since 13.03.2003 */ @SuppressWarnings("serial") public class JdkDynamicProxyTests extends AbstractAopProxyTests implements Serializable { @Override protected Object createProxy(ProxyCreatorSupport as) { assertFalse("Not forcible CGLIB", as.isProxyTargetClass()); Object proxy = as.createAopProxy().getProxy(); assertTrue("Should be a JDK proxy: " + proxy.getClass(), AopUtils.isJdkDynamicProxy(proxy)); return proxy; } @Override protected AopProxy createAopProxy(AdvisedSupport as) { return new JdkDynamicAopProxy(as); } @Test(expected = IllegalArgumentException.class) public void testNullConfig() { new JdkDynamicAopProxy(null); } @Test public void testProxyIsJustInterface() throws Throwable { TestBean raw = new TestBean(); raw.setAge(32); AdvisedSupport pc = new AdvisedSupport(ITestBean.class); pc.setTarget(raw); JdkDynamicAopProxy aop = new JdkDynamicAopProxy(pc); Object proxy = aop.getProxy(); assertTrue(proxy instanceof ITestBean); assertFalse(proxy instanceof TestBean); } @Test public void testInterceptorIsInvokedWithNoTarget() throws Throwable { // Test return value final int age = 25; MethodInterceptor mi = (invocation -> age); AdvisedSupport pc = new AdvisedSupport(ITestBean.class); pc.addAdvice(mi); AopProxy aop = createAopProxy(pc); ITestBean tb = (ITestBean) aop.getProxy(); assertEquals("correct return value", age, tb.getAge()); } @Test public void testTargetCanGetInvocationWithPrivateClass() throws Throwable { final ExposedInvocationTestBean expectedTarget = new ExposedInvocationTestBean() { @Override protected void assertions(MethodInvocation invocation) { assertEquals(this, invocation.getThis()); assertEquals("Invocation should be on ITestBean: " + invocation.getMethod(), ITestBean.class, invocation.getMethod().getDeclaringClass()); } }; AdvisedSupport pc = new AdvisedSupport(ITestBean.class, IOther.class); pc.addAdvice(ExposeInvocationInterceptor.INSTANCE); TrapTargetInterceptor tii = new TrapTargetInterceptor() { @Override public Object invoke(MethodInvocation invocation) throws Throwable { // Assert that target matches BEFORE invocation returns assertEquals("Target is correct", expectedTarget, invocation.getThis()); return super.invoke(invocation); } }; pc.addAdvice(tii); pc.setTarget(expectedTarget); AopProxy aop = createAopProxy(pc); ITestBean tb = (ITestBean) aop.getProxy(); tb.getName(); } @Test public void testProxyNotWrappedIfIncompatible() { FooBar bean = new FooBar(); ProxyCreatorSupport as = new ProxyCreatorSupport(); as.setInterfaces(Foo.class); as.setTarget(bean); Foo proxy = (Foo) createProxy(as); assertSame("Target should be returned when return types are incompatible", bean, proxy.getBarThis()); assertSame("Proxy should be returned when return types are compatible", proxy, proxy.getFooThis()); } @Test public void testEqualsAndHashCodeDefined() throws Exception { AdvisedSupport as = new AdvisedSupport(Named.class); as.setTarget(new Person()); JdkDynamicAopProxy aopProxy = new JdkDynamicAopProxy(as); Named proxy = (Named) aopProxy.getProxy(); Named named = new Person(); assertEquals("equals()", proxy, named); assertEquals("hashCode()", proxy.hashCode(), named.hashCode()); } @Test // SPR-13328 public void testVarargsWithEnumArray() throws Exception { ProxyFactory proxyFactory = new ProxyFactory(new VarargTestBean()); VarargTestInterface proxy = (VarargTestInterface) proxyFactory.getProxy(); assertTrue(proxy.doWithVarargs(MyEnum.A, MyOtherEnum.C)); } public interface Foo { Bar getBarThis(); Foo getFooThis(); } public interface Bar { } public static class FooBar implements Foo, Bar { @Override public Bar getBarThis() { return this; } @Override public Foo getFooThis() { return this; } } public interface Named { String getName(); @Override boolean equals(Object other); @Override int hashCode(); } public static class Person implements Named { private final String name = "Rob Harrop"; @Override public String getName() { return this.name; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; if (!name.equals(person.name)) return false; return true; } @Override public int hashCode() { return name.hashCode(); } } public interface VarargTestInterface { <V extends MyInterface> boolean doWithVarargs(V... args); } public static class VarargTestBean implements VarargTestInterface { @SuppressWarnings("unchecked") @Override public <V extends MyInterface> boolean doWithVarargs(V... args) { return true; } } public interface MyInterface { } public enum MyEnum implements MyInterface { A, B; } public enum MyOtherEnum implements MyInterface { C, D; } }