diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java index 564fb650202..3c4417cbe4b 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java @@ -130,8 +130,8 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac protected static AspectJAnnotation findAspectJAnnotationOnMethod(Method method) { Class[] classesToLookFor = new Class[] { Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class}; - for (Class c : classesToLookFor) { - AspectJAnnotation foundAnnotation = findAnnotation(method, (Class) c); + for (Class clazz : classesToLookFor) { + AspectJAnnotation foundAnnotation = findAnnotation(method, (Class) clazz); if (foundAnnotation != null) { return foundAnnotation; } diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java b/spring-context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java index f611eab5807..e2f8681e181 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java @@ -131,9 +131,14 @@ public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperati Collection annOps = provider.getCacheOperations(annotationParser); if (annOps != null) { if (ops == null) { - ops = new ArrayList<>(); + ops = annOps; + } + else { + Collection combined = new ArrayList<>(ops.size() + annOps.size()); + combined.addAll(ops); + combined.addAll(annOps); + ops = combined; } - ops.addAll(annOps); } } return ops; diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java index be1641e99eb..72a4d8a1b1e 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java @@ -159,7 +159,7 @@ public abstract class AnnotationConfigUtils { } } - Set beanDefs = new LinkedHashSet<>(4); + Set beanDefs = new LinkedHashSet<>(8); if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); @@ -200,6 +200,7 @@ public abstract class AnnotationConfigUtils { def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } + if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); diff --git a/spring-context/src/main/java/org/springframework/context/event/DefaultEventListenerFactory.java b/spring-context/src/main/java/org/springframework/context/event/DefaultEventListenerFactory.java index 02d71937c5b..b0ffe7516a1 100644 --- a/spring-context/src/main/java/org/springframework/context/event/DefaultEventListenerFactory.java +++ b/spring-context/src/main/java/org/springframework/context/event/DefaultEventListenerFactory.java @@ -24,6 +24,7 @@ import org.springframework.core.Ordered; /** * Default {@link EventListenerFactory} implementation that supports the * regular {@link EventListener} annotation. + * *

Used as "catch-all" implementation by default. * * @author Stephane Nicoll @@ -33,14 +34,16 @@ public class DefaultEventListenerFactory implements EventListenerFactory, Ordere private int order = LOWEST_PRECEDENCE; + + public void setOrder(int order) { + this.order = order; + } + @Override public int getOrder() { return this.order; } - public void setOrder(int order) { - this.order = order; - } public boolean supportsMethod(Method method) { return true; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HandlerMethodAnnotationDetectionTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HandlerMethodAnnotationDetectionTests.java index f0e4e976a1b..91ffe9753e7 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HandlerMethodAnnotationDetectionTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HandlerMethodAnnotationDetectionTests.java @@ -67,20 +67,20 @@ public class HandlerMethodAnnotationDetectionTests { public static Object[][] handlerTypes() { return new Object[][] { - { SimpleController.class, true }, // CGLib proxy + { SimpleController.class, true }, // CGLIB proxy { SimpleController.class, false }, - { AbstractClassController.class, true }, // CGLib proxy + { AbstractClassController.class, true }, // CGLIB proxy { AbstractClassController.class, false }, - { ParameterizedAbstractClassController.class, true }, // CGLib proxy + { ParameterizedAbstractClassController.class, true }, // CGLIB proxy { ParameterizedAbstractClassController.class, false }, - { ParameterizedSubclassOverridesDefaultMappings.class, true }, // CGLib proxy + { ParameterizedSubclassOverridesDefaultMappings.class, true }, // CGLIB proxy { ParameterizedSubclassOverridesDefaultMappings.class, false }, // TODO [SPR-9517] Enable ParameterizedSubclassDoesNotOverrideConcreteImplementationsFromGenericAbstractSuperclass test cases - // { ParameterizedSubclassDoesNotOverrideConcreteImplementationsFromGenericAbstractSuperclass.class, true }, // CGLib proxy + // { ParameterizedSubclassDoesNotOverrideConcreteImplementationsFromGenericAbstractSuperclass.class, true }, // CGLIB proxy // { ParameterizedSubclassDoesNotOverrideConcreteImplementationsFromGenericAbstractSuperclass.class, false }, { InterfaceController.class, true }, // JDK dynamic proxy @@ -88,7 +88,7 @@ public class HandlerMethodAnnotationDetectionTests { { ParameterizedInterfaceController.class, false }, // no AOP - { SupportClassController.class, true }, // CGLib proxy + { SupportClassController.class, true }, // CGLIB proxy { SupportClassController.class, false } }; @@ -100,7 +100,8 @@ public class HandlerMethodAnnotationDetectionTests { private ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver(); - public HandlerMethodAnnotationDetectionTests(final Class controllerType, boolean useAutoProxy) { + + public HandlerMethodAnnotationDetectionTests(Class controllerType, boolean useAutoProxy) { GenericWebApplicationContext context = new GenericWebApplicationContext(); context.registerBeanDefinition("controller", new RootBeanDefinition(controllerType)); context.registerBeanDefinition("handlerMapping", new RootBeanDefinition(RequestMappingHandlerMapping.class)); @@ -120,12 +121,6 @@ public class HandlerMethodAnnotationDetectionTests { context.close(); } - class TestPointcut extends StaticMethodMatcherPointcut { - @Override - public boolean matches(Method method, @Nullable Class clazz) { - return method.getName().equals("hashCode"); - } - } @Test public void testRequestMappingMethod() throws Exception { @@ -203,9 +198,9 @@ public class HandlerMethodAnnotationDetectionTests { public abstract String handleException(Exception exception); } + /** * CONTROLLER WITH ABSTRACT CLASS - * *

All annotations can be on methods in the abstract class except parameter annotations. */ static class AbstractClassController extends MappingAbstractClass { @@ -232,10 +227,10 @@ public class HandlerMethodAnnotationDetectionTests { } } - // SPR-9374 + // SPR-9374 @RequestMapping - static interface MappingInterface { + interface MappingInterface { @InitBinder void initBinder(WebDataBinder dataBinder, @RequestParam("datePattern") String thePattern); @@ -252,14 +247,11 @@ public class HandlerMethodAnnotationDetectionTests { String handleException(Exception exception); } + /** * CONTROLLER WITH INTERFACE - * - * JDK Dynamic proxy: - * All annotations must be on the interface. - * - * Without AOP: - * Annotations can be on interface methods except parameter annotations. + *

JDK Dynamic proxy: All annotations must be on the interface. + *

Without AOP: Annotations can be on interface methods except parameter annotations. */ static class InterfaceController implements MappingInterface { @@ -304,9 +296,9 @@ public class HandlerMethodAnnotationDetectionTests { public abstract String handleException(Exception exception); } + /** * CONTROLLER WITH PARAMETERIZED BASE CLASS - * *

All annotations can be on methods in the abstract class except parameter annotations. */ static class ParameterizedAbstractClassController extends MappingGenericAbstractClass { @@ -333,6 +325,7 @@ public class HandlerMethodAnnotationDetectionTests { } } + @Controller static abstract class MappedGenericAbstractClassWithConcreteImplementations { @@ -353,6 +346,7 @@ public class HandlerMethodAnnotationDetectionTests { public abstract String handleException(Exception exception); } + static class ParameterizedSubclassDoesNotOverrideConcreteImplementationsFromGenericAbstractSuperclass extends MappedGenericAbstractClassWithConcreteImplementations { @@ -375,6 +369,7 @@ public class HandlerMethodAnnotationDetectionTests { } } + @Controller static abstract class GenericAbstractClassDeclaresDefaultMappings { @@ -395,6 +390,7 @@ public class HandlerMethodAnnotationDetectionTests { public abstract String handleException(Exception exception); } + static class ParameterizedSubclassOverridesDefaultMappings extends GenericAbstractClassDeclaresDefaultMappings { @@ -425,8 +421,9 @@ public class HandlerMethodAnnotationDetectionTests { } } + @RequestMapping - static interface MappingGenericInterface { + interface MappingGenericInterface { @InitBinder void initBinder(WebDataBinder dataBinder, A thePattern); @@ -443,11 +440,10 @@ public class HandlerMethodAnnotationDetectionTests { String handleException(Exception exception); } + /** * CONTROLLER WITH PARAMETERIZED INTERFACE - * *

All annotations can be on interface except parameter annotations. - * *

Cannot be used as JDK dynamic proxy since parameterized interface does not contain type information. */ static class ParameterizedInterfaceController implements MappingGenericInterface { @@ -483,7 +479,6 @@ public class HandlerMethodAnnotationDetectionTests { /** * SPR-8248 - * *

Support class contains all annotations. Subclass has type-level @{@link RequestMapping}. */ @Controller diff --git a/src/test/java/org/springframework/cache/annotation/EnableCachingIntegrationTests.java b/src/test/java/org/springframework/cache/annotation/EnableCachingIntegrationTests.java index bf16d0cdd75..d23b77d757a 100644 --- a/src/test/java/org/springframework/cache/annotation/EnableCachingIntegrationTests.java +++ b/src/test/java/org/springframework/cache/annotation/EnableCachingIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 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. @@ -70,6 +70,7 @@ public class EnableCachingIntegrationTests { } } + private void assertCacheProxying(AnnotationConfigApplicationContext ctx) { FooRepository repo = ctx.getBean(FooRepository.class); @@ -89,6 +90,7 @@ public class EnableCachingIntegrationTests { @Configuration @EnableCaching(proxyTargetClass=true) static class ProxyTargetClassCachingConfig { + @Bean CacheManager mgr() { return new NoOpCacheManager(); @@ -98,6 +100,7 @@ public class EnableCachingIntegrationTests { @Configuration static class Config { + @Bean FooRepository fooRepository() { return new DummyFooRepository(); @@ -108,6 +111,7 @@ public class EnableCachingIntegrationTests { @Configuration @EnableCaching(mode=AdviceMode.ASPECTJ) static class AspectJCacheConfig { + @Bean CacheManager cacheManager() { return new NoOpCacheManager(); @@ -116,6 +120,7 @@ public class EnableCachingIntegrationTests { interface FooRepository { + List findAll(); } @@ -129,4 +134,5 @@ public class EnableCachingIntegrationTests { return Collections.emptyList(); } } + } diff --git a/src/test/java/org/springframework/transaction/annotation/EnableTransactionManagementIntegrationTests.java b/src/test/java/org/springframework/transaction/annotation/EnableTransactionManagementIntegrationTests.java index 8dbe13d384c..25a21718d8d 100644 --- a/src/test/java/org/springframework/transaction/annotation/EnableTransactionManagementIntegrationTests.java +++ b/src/test/java/org/springframework/transaction/annotation/EnableTransactionManagementIntegrationTests.java @@ -166,10 +166,30 @@ public class EnableTransactionManagementIntegrationTests { } + private void assertTxProxying(AnnotationConfigApplicationContext ctx) { + FooRepository repo = ctx.getBean(FooRepository.class); + + boolean isTxProxy = false; + if (AopUtils.isAopProxy(repo)) { + for (Advisor advisor : ((Advised)repo).getAdvisors()) { + if (advisor instanceof BeanFactoryTransactionAttributeSourceAdvisor) { + isTxProxy = true; + break; + } + } + } + assertTrue("FooRepository is not a TX proxy", isTxProxy); + + // trigger a transaction + repo.findAll(); + } + + @Configuration @EnableTransactionManagement @ImportResource("org/springframework/transaction/annotation/enable-caching.xml") static class EnableTxAndCachingConfig { + @Bean public PlatformTransactionManager txManager() { return new CallCountingTransactionManager(); @@ -194,6 +214,7 @@ public class EnableTransactionManagementIntegrationTests { @Configuration @EnableTransactionManagement static class ImplicitTxManagerConfig { + @Bean public PlatformTransactionManager txManager() { return new CallCountingTransactionManager(); @@ -209,6 +230,7 @@ public class EnableTransactionManagementIntegrationTests { @Configuration @EnableTransactionManagement static class ExplicitTxManagerConfig implements TransactionManagementConfigurer { + @Bean public PlatformTransactionManager txManager1() { return new CallCountingTransactionManager(); @@ -230,28 +252,11 @@ public class EnableTransactionManagementIntegrationTests { } } - private void assertTxProxying(AnnotationConfigApplicationContext ctx) { - FooRepository repo = ctx.getBean(FooRepository.class); - - boolean isTxProxy = false; - if (AopUtils.isAopProxy(repo)) { - for (Advisor advisor : ((Advised)repo).getAdvisors()) { - if (advisor instanceof BeanFactoryTransactionAttributeSourceAdvisor) { - isTxProxy = true; - break; - } - } - } - assertTrue("FooRepository is not a TX proxy", isTxProxy); - - // trigger a transaction - repo.findAll(); - } - @Configuration @EnableTransactionManagement static class DefaultTxManagerNameConfig { + @Bean PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); @@ -262,6 +267,7 @@ public class EnableTransactionManagementIntegrationTests { @Configuration @EnableTransactionManagement static class CustomTxManagerNameConfig { + @Bean PlatformTransactionManager txManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); @@ -272,6 +278,7 @@ public class EnableTransactionManagementIntegrationTests { @Configuration @EnableTransactionManagement static class NonConventionalTxManagerNameConfig { + @Bean PlatformTransactionManager txManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); @@ -282,6 +289,7 @@ public class EnableTransactionManagementIntegrationTests { @Configuration @EnableTransactionManagement(proxyTargetClass=true) static class ProxyTargetClassTxConfig { + @Bean PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); @@ -292,6 +300,7 @@ public class EnableTransactionManagementIntegrationTests { @Configuration @EnableTransactionManagement(mode=AdviceMode.ASPECTJ) static class AspectJTxConfig { + @Bean PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); @@ -301,6 +310,7 @@ public class EnableTransactionManagementIntegrationTests { @Configuration static class Config { + @Bean FooRepository fooRepository() { JdbcFooRepository repos = new JdbcFooRepository(); @@ -318,6 +328,7 @@ public class EnableTransactionManagementIntegrationTests { interface FooRepository { + List findAll(); } @@ -335,6 +346,7 @@ public class EnableTransactionManagementIntegrationTests { } } + @Repository static class DummyFooRepository implements FooRepository { @@ -344,4 +356,5 @@ public class EnableTransactionManagementIntegrationTests { return Collections.emptyList(); } } + }