diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java index 91ab40742ab..7b56b21a907 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -49,13 +49,13 @@ import org.springframework.aop.ProxyMethodInvocation; import org.springframework.aop.framework.autoproxy.ProxyCreationContext; import org.springframework.aop.interceptor.ExposeInvocationInterceptor; import org.springframework.aop.support.AbstractExpressionPointcut; -import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils; import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.core.BridgeMethodResolver; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -289,10 +289,9 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut } @Override - public boolean matches(Method method, @Nullable Class targetClass, boolean beanHasIntroductions) { + public boolean matches(Method method, @Nullable Class targetClass, boolean hasIntroductions) { obtainPointcutExpression(); - Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass); - ShadowMatch shadowMatch = getShadowMatch(targetMethod, method); + ShadowMatch shadowMatch = getTargetShadowMatch(method, targetClass); // Special handling for this, target, @this, @target, @annotation // in Spring - we can optimize since we know we have exactly this class, @@ -305,7 +304,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut } else { // the maybe case - if (beanHasIntroductions) { + if (hasIntroductions) { return true; } // A match test returned maybe - if there are any subtype sensitive variables @@ -331,8 +330,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut @Override public boolean matches(Method method, @Nullable Class targetClass, Object... args) { obtainPointcutExpression(); - ShadowMatch shadowMatch = getShadowMatch(AopUtils.getMostSpecificMethod(method, targetClass), method); - ShadowMatch originalShadowMatch = getShadowMatch(method, method); + ShadowMatch shadowMatch = getTargetShadowMatch(method, targetClass); // Bind Spring AOP proxy to AspectJ "this" and Spring AOP target to AspectJ target, // consistent with return of MethodInvocationProceedingJoinPoint @@ -367,7 +365,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut *

See SPR-2979 for the original bug. */ if (pmi != null && thisObject != null) { // there is a current invocation - RuntimeTestWalker originalMethodResidueTest = getRuntimeTestWalker(originalShadowMatch); + RuntimeTestWalker originalMethodResidueTest = getRuntimeTestWalker(getShadowMatch(method, method)); if (!originalMethodResidueTest.testThisInstanceOfResidue(thisObject.getClass())) { return false; } @@ -427,6 +425,23 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut invocation.setUserAttribute(resolveExpression(), jpm); } + private ShadowMatch getTargetShadowMatch(Method method, @Nullable Class targetClass) { + Method targetMethod = method; + if (targetClass != null) { + targetMethod = ClassUtils.getMostSpecificMethod(method, ClassUtils.getUserClass(targetClass)); + if (targetMethod.getDeclaringClass().isInterface()) { + Set> ifcs = ClassUtils.getAllInterfacesForClassAsSet(targetClass); + if (ifcs.size() > 1) { + Class compositeInterface = ClassUtils.createCompositeInterface( + ClassUtils.toClassArray(ifcs), targetClass.getClassLoader()); + targetMethod = ClassUtils.getMostSpecificMethod(targetMethod, compositeInterface); + } + } + } + targetMethod = BridgeMethodResolver.findBridgedMethod(targetMethod); + return getShadowMatch(targetMethod, method); + } + private ShadowMatch getShadowMatch(Method targetMethod, Method originalMethod) { // Avoid lock contention for known Methods through concurrent access... ShadowMatch shadowMatch = this.shadowMatchCache.get(targetMethod); @@ -434,9 +449,9 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut synchronized (this.shadowMatchCache) { // Not found - now check again with full lock... PointcutExpression fallbackExpression = null; - Method methodToMatch = targetMethod; shadowMatch = this.shadowMatchCache.get(targetMethod); if (shadowMatch == null) { + Method methodToMatch = targetMethod; try { try { shadowMatch = obtainPointcutExpression().matchesMethodExecution(methodToMatch); @@ -459,7 +474,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut try { shadowMatch = obtainPointcutExpression().matchesMethodExecution(methodToMatch); } - catch (ReflectionWorldException ex3) { + catch (ReflectionWorldException ex) { // Could neither introspect the target class nor the proxy class -> // let's try the original method's declaring class before we give up... try { @@ -468,7 +483,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch); } } - catch (ReflectionWorldException ex4) { + catch (ReflectionWorldException ex2) { fallbackExpression = null; } } diff --git a/spring-aop/src/main/java/org/springframework/aop/support/MethodMatchers.java b/spring-aop/src/main/java/org/springframework/aop/support/MethodMatchers.java index dae5b46a832..30de25c2c1e 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/MethodMatchers.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/MethodMatchers.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -90,8 +90,8 @@ public abstract class MethodMatchers { */ public static boolean matches(MethodMatcher mm, Method method, @Nullable Class targetClass, boolean hasIntroductions) { Assert.notNull(mm, "MethodMatcher must not be null"); - return ((mm instanceof IntroductionAwareMethodMatcher && - ((IntroductionAwareMethodMatcher) mm).matches(method, targetClass, hasIntroductions)) || + return (mm instanceof IntroductionAwareMethodMatcher ? + ((IntroductionAwareMethodMatcher) mm).matches(method, targetClass, hasIntroductions) : mm.matches(method, targetClass)); } diff --git a/spring-beans/src/test/java/org/springframework/tests/sample/beans/AgeHolder.java b/spring-beans/src/test/java/org/springframework/tests/sample/beans/AgeHolder.java new file mode 100644 index 00000000000..ebc0932df93 --- /dev/null +++ b/spring-beans/src/test/java/org/springframework/tests/sample/beans/AgeHolder.java @@ -0,0 +1,29 @@ +/* + * Copyright 2002-2018 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.tests.sample.beans; + +public interface AgeHolder { + + default int age() { + return getAge(); + } + + int getAge(); + + void setAge(int age); + +} diff --git a/spring-beans/src/test/java/org/springframework/tests/sample/beans/ITestBean.java b/spring-beans/src/test/java/org/springframework/tests/sample/beans/ITestBean.java index b467348a93d..796e7e234ce 100644 --- a/spring-beans/src/test/java/org/springframework/tests/sample/beans/ITestBean.java +++ b/spring-beans/src/test/java/org/springframework/tests/sample/beans/ITestBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * Copyright 2002-2018 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. @@ -27,11 +27,7 @@ import java.io.IOException; * @author Rod Johnson * @author Juergen Hoeller */ -public interface ITestBean { - - int getAge(); - - void setAge(int age); +public interface ITestBean extends AgeHolder { String getName(); diff --git a/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java b/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java index 58f55bd6ad8..760181a4aeb 100644 --- a/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java +++ b/spring-context/src/test/java/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2018 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. @@ -185,7 +185,7 @@ public class AspectJAutoProxyCreatorTests { // Create a child factory with a bean that should be woven RootBeanDefinition bd = new RootBeanDefinition(TestBean.class); bd.getPropertyValues().addPropertyValue(new PropertyValue("name", "Adrian")) - .addPropertyValue(new PropertyValue("age", new Integer(34))); + .addPropertyValue(new PropertyValue("age", 34)); childAc.registerBeanDefinition("adrian2", bd); // Register the advisor auto proxy creator with subclass childAc.registerBeanDefinition(AnnotationAwareAspectJAutoProxyCreator.class.getName(), new RootBeanDefinition( @@ -270,25 +270,45 @@ public class AspectJAutoProxyCreatorTests { assertEquals(3, adrian1.getAge()); } + @Test + public void testTwoAdviceAspect() { + ClassPathXmlApplicationContext bf = newContext("twoAdviceAspect.xml"); + + ITestBean adrian1 = (ITestBean) bf.getBean("adrian"); + testAgeAspect(adrian1, 0, 2); + } + @Test public void testTwoAdviceAspectSingleton() { - doTestTwoAdviceAspectWith("twoAdviceAspect.xml"); + ClassPathXmlApplicationContext bf = newContext("twoAdviceAspectSingleton.xml"); + + ITestBean adrian1 = (ITestBean) bf.getBean("adrian"); + testAgeAspect(adrian1, 0, 1); + ITestBean adrian2 = (ITestBean) bf.getBean("adrian"); + assertNotSame(adrian1, adrian2); + testAgeAspect(adrian2, 2, 1); } @Test public void testTwoAdviceAspectPrototype() { - doTestTwoAdviceAspectWith("twoAdviceAspectPrototype.xml"); - } + ClassPathXmlApplicationContext bf = newContext("twoAdviceAspectPrototype.xml"); - private void doTestTwoAdviceAspectWith(String location) { - ClassPathXmlApplicationContext bf = newContext(location); - - boolean aspectSingleton = bf.isSingleton("aspect"); ITestBean adrian1 = (ITestBean) bf.getBean("adrian"); - testPrototype(adrian1, 0); + testAgeAspect(adrian1, 0, 1); ITestBean adrian2 = (ITestBean) bf.getBean("adrian"); assertNotSame(adrian1, adrian2); - testPrototype(adrian2, aspectSingleton ? 2 : 0); + testAgeAspect(adrian2, 0, 1); + } + + private void testAgeAspect(ITestBean adrian, int start, int increment) { + assertTrue(AopUtils.isAopProxy(adrian)); + adrian.setName(""); + assertEquals(start, adrian.age()); + int newAge = 32; + adrian.setAge(newAge); + assertEquals(start + increment, adrian.age()); + adrian.setAge(0); + assertEquals(start + increment * 2, adrian.age()); } @Test @@ -312,18 +332,6 @@ public class AspectJAutoProxyCreatorTests { assertEquals(68, adrian.getAge()); } - private void testPrototype(ITestBean adrian1, int start) { - assertTrue(AopUtils.isAopProxy(adrian1)); - //TwoAdviceAspect twoAdviceAspect = (TwoAdviceAspect) bf.getBean(TwoAdviceAspect.class.getName()); - adrian1.setName(""); - assertEquals(start++, adrian1.getAge()); - int newAge = 32; - adrian1.setAge(newAge); - assertEquals(start++, adrian1.getAge()); - adrian1.setAge(0); - assertEquals(start++, adrian1.getAge()); - } - @Test public void testForceProxyTargetClass() { ClassPathXmlApplicationContext bf = newContext("aspectsWithCGLIB.xml"); diff --git a/spring-context/src/test/java/test/aspect/PerTargetAspect.java b/spring-context/src/test/java/test/aspect/PerTargetAspect.java index aaa2c6ed45f..b6ff21f547a 100644 --- a/spring-context/src/test/java/test/aspect/PerTargetAspect.java +++ b/spring-context/src/test/java/test/aspect/PerTargetAspect.java @@ -1,6 +1,19 @@ -/** +/* + * Copyright 2002-2018 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 test.aspect; import org.aspectj.lang.annotation.Around; diff --git a/spring-context/src/test/java/test/aspect/TwoAdviceAspect.java b/spring-context/src/test/java/test/aspect/TwoAdviceAspect.java index 85eb6b7557d..09ae3b60585 100644 --- a/spring-context/src/test/java/test/aspect/TwoAdviceAspect.java +++ b/spring-context/src/test/java/test/aspect/TwoAdviceAspect.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2018 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. @@ -23,15 +23,17 @@ import org.aspectj.lang.annotation.Before; @Aspect public class TwoAdviceAspect { + private int totalCalls; - @Around("execution(* getAge())") + @Around("execution(* org.springframework.tests.sample.beans.ITestBean.age())") public int returnCallCount(ProceedingJoinPoint pjp) throws Exception { return totalCalls; } - @Before("execution(* setAge(int)) && args(newAge)") + @Before("execution(* org.springframework.tests.sample.beans.ITestBean.setAge(int)) && args(newAge)") public void countSet(int newAge) throws Exception { ++totalCalls; } -} \ No newline at end of file + +} diff --git a/spring-context/src/test/resources/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests-twoAdviceAspect.xml b/spring-context/src/test/resources/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests-twoAdviceAspect.xml index e00377721c4..b56770de442 100644 --- a/spring-context/src/test/resources/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests-twoAdviceAspect.xml +++ b/spring-context/src/test/resources/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests-twoAdviceAspect.xml @@ -7,9 +7,13 @@ - - - + + + + + + + diff --git a/spring-context/src/test/resources/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests-twoAdviceAspectPrototype.xml b/spring-context/src/test/resources/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests-twoAdviceAspectPrototype.xml index 9505a844d7f..54d799a0f7b 100644 --- a/spring-context/src/test/resources/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests-twoAdviceAspectPrototype.xml +++ b/spring-context/src/test/resources/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests-twoAdviceAspectPrototype.xml @@ -5,8 +5,7 @@ - + diff --git a/spring-context/src/test/resources/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests-twoAdviceAspectSingleton.xml b/spring-context/src/test/resources/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests-twoAdviceAspectSingleton.xml new file mode 100644 index 00000000000..e00377721c4 --- /dev/null +++ b/spring-context/src/test/resources/org/springframework/aop/aspectj/autoproxy/AspectJAutoProxyCreatorTests-twoAdviceAspectSingleton.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/spring-core/src/main/java/org/springframework/util/ClassUtils.java b/spring-core/src/main/java/org/springframework/util/ClassUtils.java index 8cbd7024cba..c3bd9c9d512 100644 --- a/spring-core/src/main/java/org/springframework/util/ClassUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ClassUtils.java @@ -348,13 +348,16 @@ public abstract class ClassUtils { return true; } try { - return (clazz == classLoader.loadClass(clazz.getName())); - // Else: different class with same name found + if (clazz.getClassLoader() == classLoader) { + return true; + } } - catch (ClassNotFoundException ex) { - // No corresponding class found at all - return false; + catch (SecurityException ex) { + // Fall through to loadable check below } + + // Visible if same Class can be loaded from given ClassLoader + return isLoadable(clazz, classLoader); } /** @@ -392,12 +395,29 @@ public abstract class ClassUtils { } } catch (SecurityException ex) { - // Fall through to Class reference comparison below + // Fall through to loadable check below } // Fallback for ClassLoaders without parent/child relationship: // safe if same Class can be loaded from given ClassLoader - return (classLoader != null && isVisible(clazz, classLoader)); + return (classLoader != null && isLoadable(clazz, classLoader)); + } + + /** + * Check whether the given class is loadable in the given ClassLoader. + * @param clazz the class to check (typically an interface) + * @param classLoader the ClassLoader to check against + * @since 5.0.6 + */ + private static boolean isLoadable(Class clazz, ClassLoader classLoader) { + try { + return (clazz == classLoader.loadClass(clazz.getName())); + // Else: different class with same name found + } + catch (ClassNotFoundException ex) { + // No corresponding class found at all + return false; + } } /** @@ -711,14 +731,16 @@ public abstract class ClassUtils { public static Set> getAllInterfacesForClassAsSet(Class clazz, @Nullable ClassLoader classLoader) { Assert.notNull(clazz, "Class must not be null"); if (clazz.isInterface() && isVisible(clazz, classLoader)) { - return Collections.>singleton(clazz); + return Collections.singleton(clazz); } Set> interfaces = new LinkedHashSet<>(); Class current = clazz; while (current != null) { Class[] ifcs = current.getInterfaces(); for (Class ifc : ifcs) { - interfaces.addAll(getAllInterfacesForClassAsSet(ifc, classLoader)); + if (isVisible(ifc, classLoader)) { + interfaces.add(ifc); + } } current = current.getSuperclass(); } @@ -1211,8 +1233,7 @@ public abstract class ClassUtils { * {@code targetClass} doesn't implement it or is {@code null} */ public static Method getMostSpecificMethod(Method method, @Nullable Class targetClass) { - if (isOverridable(method, targetClass) && - targetClass != null && targetClass != method.getDeclaringClass()) { + if (targetClass != null && targetClass != method.getDeclaringClass() && isOverridable(method, targetClass)) { try { if (Modifier.isPublic(method.getModifiers())) { try { diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/MethodMapTransactionAttributeSource.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/MethodMapTransactionAttributeSource.java index a4aaf3c9702..a2898fecff3 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/MethodMapTransactionAttributeSource.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/MethodMapTransactionAttributeSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -32,6 +32,7 @@ import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.PatternMatchUtils; +import org.springframework.util.ReflectionUtils; /** * Simple {@link TransactionAttributeSource} implementation that @@ -144,7 +145,7 @@ public class MethodMapTransactionAttributeSource Assert.notNull(mappedName, "Mapped name must not be null"); String name = clazz.getName() + '.' + mappedName; - Method[] methods = clazz.getDeclaredMethods(); + Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); List matchingMethods = new ArrayList<>(); for (Method method : methods) { if (isMatch(method.getName(), mappedName)) { @@ -156,7 +157,7 @@ public class MethodMapTransactionAttributeSource "Couldn't find method '" + mappedName + "' on class [" + clazz.getName() + "]"); } - // register all matching methods + // Register all matching methods for (Method method : matchingMethods) { String regMethodName = this.methodNameMap.get(method); if (regMethodName == null || (!regMethodName.equals(name) && regMethodName.length() <= name.length())) { diff --git a/spring-tx/src/test/java/org/springframework/transaction/interceptor/BeanFactoryTransactionTests.java b/spring-tx/src/test/java/org/springframework/transaction/interceptor/BeanFactoryTransactionTests.java index 48461bc05ef..a9f433e5e82 100644 --- a/spring-tx/src/test/java/org/springframework/transaction/interceptor/BeanFactoryTransactionTests.java +++ b/spring-tx/src/test/java/org/springframework/transaction/interceptor/BeanFactoryTransactionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2018 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. @@ -45,7 +45,6 @@ import org.springframework.transaction.TransactionStatus; import static org.junit.Assert.*; import static org.mockito.BDDMockito.*; - /** * Test cases for AOP transaction management. * @@ -67,7 +66,7 @@ public class BeanFactoryTransactionTests { @Test - public void testGetsAreNotTransactionalWithProxyFactory1() throws NoSuchMethodException { + public void testGetsAreNotTransactionalWithProxyFactory1() { ITestBean testBean = (ITestBean) factory.getBean("proxyFactory1"); assertTrue("testBean is a dynamic proxy", Proxy.isProxyClass(testBean.getClass())); assertFalse(testBean instanceof TransactionalProxy); @@ -75,7 +74,7 @@ public class BeanFactoryTransactionTests { } @Test - public void testGetsAreNotTransactionalWithProxyFactory2DynamicProxy() throws NoSuchMethodException { + public void testGetsAreNotTransactionalWithProxyFactory2DynamicProxy() { this.factory.preInstantiateSingletons(); ITestBean testBean = (ITestBean) factory.getBean("proxyFactory2DynamicProxy"); assertTrue("testBean is a dynamic proxy", Proxy.isProxyClass(testBean.getClass())); @@ -84,7 +83,7 @@ public class BeanFactoryTransactionTests { } @Test - public void testGetsAreNotTransactionalWithProxyFactory2Cglib() throws NoSuchMethodException { + public void testGetsAreNotTransactionalWithProxyFactory2Cglib() { ITestBean testBean = (ITestBean) factory.getBean("proxyFactory2Cglib"); assertTrue("testBean is CGLIB advised", AopUtils.isCglibProxy(testBean)); assertTrue(testBean instanceof TransactionalProxy); @@ -92,7 +91,7 @@ public class BeanFactoryTransactionTests { } @Test - public void testProxyFactory2Lazy() throws NoSuchMethodException { + public void testProxyFactory2Lazy() { ITestBean testBean = (ITestBean) factory.getBean("proxyFactory2Lazy"); assertFalse(factory.containsSingleton("target")); assertEquals(666, testBean.getAge()); @@ -100,7 +99,7 @@ public class BeanFactoryTransactionTests { } @Test - public void testCglibTransactionProxyImplementsNoInterfaces() throws NoSuchMethodException { + public void testCglibTransactionProxyImplementsNoInterfaces() { ImplementsNoInterfaces ini = (ImplementsNoInterfaces) factory.getBean("cglibNoInterfaces"); assertTrue("testBean is CGLIB advised", AopUtils.isCglibProxy(ini)); assertTrue(ini instanceof TransactionalProxy); @@ -116,7 +115,7 @@ public class BeanFactoryTransactionTests { } @Test - public void testGetsAreNotTransactionalWithProxyFactory3() throws NoSuchMethodException { + public void testGetsAreNotTransactionalWithProxyFactory3() { ITestBean testBean = (ITestBean) factory.getBean("proxyFactory3"); assertTrue("testBean is a full proxy", testBean instanceof DerivedTestBean); assertTrue(testBean instanceof TransactionalProxy); @@ -202,7 +201,7 @@ public class BeanFactoryTransactionTests { * Test that we can set the target to a dynamic TargetSource. */ @Test - public void testDynamicTargetSource() throws NoSuchMethodException { + public void testDynamicTargetSource() { // Install facade CallCountingTransactionManager txMan = new CallCountingTransactionManager(); PlatformTransactionManagerFacade.delegate = txMan;