From d45801b69004dfb6d8f98509272bbb5f38798fee Mon Sep 17 00:00:00 2001 From: Kicey <57286603+kicey@users.noreply.github.com> Date: Wed, 2 Nov 2022 10:19:37 -0400 Subject: [PATCH] GH-3931: Fix meta-annotation support for @Gateway Fixes https://github.com/spring-projects/spring-integration/issues/3931 * Update test for @AliasFor support. **Cherry-pick to `5.5.x`** # Conflicts: # spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java --- .../gateway/GatewayProxyFactoryBean.java | 6 ++- .../gateway/GatewayProxyFactoryBeanTests.java | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java index 2efdaeae94..5e0a33c2ea 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java @@ -49,6 +49,7 @@ import org.springframework.beans.factory.BeanInitializationException; import org.springframework.beans.factory.FactoryBean; import org.springframework.core.MethodParameter; import org.springframework.core.ResolvableType; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.task.AsyncListenableTaskExecutor; import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.SimpleAsyncTaskExecutor; @@ -102,6 +103,7 @@ import reactor.core.publisher.Mono; * @author Oleg Zhurakousky * @author Gary Russell * @author Artem Bilan + * @author JingPeng Xie */ public class GatewayProxyFactoryBean extends AbstractEndpoint implements TrackableComponent, FactoryBean, MethodInterceptor, BeanClassLoaderAware, @@ -486,7 +488,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint Method[] methods = ReflectionUtils.getUniqueDeclaredMethods(this.serviceInterface); for (Method method : methods) { if (Modifier.isAbstract(method.getModifiers()) - || method.getAnnotation(Gateway.class) != null + || AnnotatedElementUtils.isAnnotated(method, Gateway.class) || (method.isDefault() && this.proxyDefaultMethods)) { MethodInvocationGateway gateway = createGatewayForMethod(method); @@ -680,7 +682,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint } private MethodInvocationGateway createGatewayForMethod(Method method) { - Gateway gatewayAnnotation = method.getAnnotation(Gateway.class); + Gateway gatewayAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, Gateway.class); GatewayMethodMetadata methodMetadata = null; if (!CollectionUtils.isEmpty(this.methodMetadataMap)) { methodMetadata = this.methodMetadataMap.get(method.getName()); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayProxyFactoryBeanTests.java b/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayProxyFactoryBeanTests.java index 45991e5c5c..151b7968ae 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayProxyFactoryBeanTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayProxyFactoryBeanTests.java @@ -23,6 +23,10 @@ import static org.mockito.BDDMockito.willReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.lang.reflect.Method; import java.util.Collections; import java.util.Map; @@ -40,6 +44,7 @@ import org.springframework.beans.factory.BeanInitializationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.core.annotation.AliasFor; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.GenericConversionService; @@ -70,6 +75,7 @@ import org.springframework.util.ReflectionUtils; * @author Gunnar Hillert * @author Gary Russell * @author Artem Bilan + * @author JingPeng Xie */ public class GatewayProxyFactoryBeanTests { @@ -494,6 +500,19 @@ public class GatewayProxyFactoryBeanTests { assertThat(gateways.size()).isEqualTo(2); } + @Test + public void testAliasForSupport() throws NoSuchMethodException { + MessageChannel requestChannel = new DirectChannel(); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerSingleton("requestChannel", requestChannel); + GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean(CompositedGatewayService.class); + gpfb.setBeanFactory(beanFactory); + gpfb.afterPropertiesSet(); + Map gateways = gpfb.getGateways(); + Method sendMethod = CompositedGatewayService.class.getMethod("gatewayMethod"); + assertThat(gateways.get(sendMethod).getRequestChannel()).isEqualTo(beanFactory.getBean("requestChannel")); + } + public static void throwTestException() throws TestException { throw new TestException(); } @@ -513,6 +532,26 @@ public class GatewayProxyFactoryBeanTests { } + + @Gateway + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + @interface CompositedGateway { + + @AliasFor(annotation = Gateway.class, attribute = "requestChannel") + String requestChannelName() default ""; + + } + + + interface CompositedGatewayService { + + @CompositedGateway(requestChannelName = "requestChannel") + void gatewayMethod(); + + } + + interface HeadersParamService { Message echo(String s, @Header(MessageHeaders.TIMESTAMP) String foo);