diff --git a/spring-integration-core/src/main/java/org/springframework/integration/aop/MethodAnnotationPublisherMetadataSource.java b/spring-integration-core/src/main/java/org/springframework/integration/aop/MethodAnnotationPublisherMetadataSource.java index 0a0b197de0..151f1e9a1d 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/aop/MethodAnnotationPublisherMetadataSource.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/aop/MethodAnnotationPublisherMetadataSource.java @@ -25,6 +25,7 @@ import java.util.Set; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.integration.annotation.Publisher; import org.springframework.messaging.handler.annotation.Header; @@ -38,6 +39,7 @@ import org.springframework.util.StringUtils; * * @author Mark Fisher * @author Artem Bilan + * @author Gareth Chapman * @since 2.0 */ public class MethodAnnotationPublisherMetadataSource implements PublisherMetadataSource { @@ -137,7 +139,7 @@ public class MethodAnnotationPublisherMetadataSource implements PublisherMetadat private T getAnnotationValue(Method method, String attributeName, Class expectedType) { T value = null; for (Class annotationType : this.annotationTypes) { - Annotation annotation = AnnotationUtils.findAnnotation(method, annotationType); + Annotation annotation = AnnotatedElementUtils.findMergedAnnotation(method, annotationType); if (annotation != null) { if (value != null) { throw new IllegalStateException( @@ -152,7 +154,7 @@ public class MethodAnnotationPublisherMetadataSource implements PublisherMetadat private T getAnnotationValue(Class clazz, String attributeName, Class expectedType) { T value = null; for (Class annotationType : this.annotationTypes) { - Annotation annotation = AnnotationUtils.findAnnotation(clazz, annotationType); + Annotation annotation = AnnotatedElementUtils.findMergedAnnotation(clazz, annotationType); if (annotation != null) { if (value != null) { throw new IllegalStateException( diff --git a/spring-integration-core/src/test/java/org/springframework/integration/aop/MethodAnnotationPublisherMetadataSourceTests.java b/spring-integration-core/src/test/java/org/springframework/integration/aop/MethodAnnotationPublisherMetadataSourceTests.java index 03b5bbbb26..43b4756710 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/aop/MethodAnnotationPublisherMetadataSourceTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/aop/MethodAnnotationPublisherMetadataSourceTests.java @@ -19,14 +19,17 @@ package org.springframework.integration.aop; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; import java.util.Map; import org.junit.Test; +import org.springframework.core.annotation.AliasFor; +import org.springframework.integration.annotation.Publisher; import org.springframework.messaging.handler.annotation.Header; import org.springframework.messaging.handler.annotation.Payload; -import org.springframework.integration.annotation.Publisher; /** * @author Mark Fisher @@ -105,9 +108,31 @@ public class MethodAnnotationPublisherMetadataSourceTests { source.getPayloadExpression(method); } - private static Method getMethod(String name, Class ... params) { + @Test + public void explicitAnnotationAttributeOverride() { + Method method = getMethod("methodWithExplicitAnnotationAttributeOverride"); + String channelName = source.getChannelName(method); + assertEquals("foo", channelName); + } + + @Test + public void explicitAnnotationAttributeOverrideOnDeclaringClass() { + Method method = getMethodFromTestClass("methodWithAnnotationOnTheDeclaringClass"); + String channelName = source.getChannelName(method); + assertEquals("bar", channelName); + } + + private static Method getMethodFromTestClass(String name, Class... params) { + return getMethodFromClass(TestClass.class, name, params); + } + + private static Method getMethod(String name, Class... params) { + return getMethodFromClass(MethodAnnotationPublisherMetadataSourceTests.class, name, params); + } + + private static Method getMethodFromClass(Class sourceClass, String name, Class... params) { try { - return MethodAnnotationPublisherMetadataSourceTests.class.getMethod(name, params); + return sourceClass.getMethod(name, params); } catch (Exception e) { throw new RuntimeException("failed to resolve method", e); @@ -156,4 +181,21 @@ public class MethodAnnotationPublisherMetadataSourceTests { public void methodWithVoidReturnAndNoPayloadAnnotation(String payload) { } + @Publisher + @Retention(RetentionPolicy.RUNTIME) + public @interface CustomPublisher { + @AliasFor(annotation = Publisher.class, attribute = "channel") + String custom(); + } + + @CustomPublisher(custom = "foo") + public void methodWithExplicitAnnotationAttributeOverride() { + } + + @CustomPublisher(custom = "bar") + public class TestClass { + public void methodWithAnnotationOnTheDeclaringClass() { + } + } + }