From 5a66854c67680c372c5173caad5fa54558b52c19 Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Thu, 20 Jul 2017 17:54:12 -0400 Subject: [PATCH] IntegrationFlow: optional `@MessagingGateway` When we use `IntegrationFlows.from(Class)`, we don't need to require present for `@MessagingGateway`, we can just synthesize it with the default properties This way we can simply make gateway proxies for the `java.util.function` interfaces which should be useful for Spring Cloud Function --- .../integration/dsl/IntegrationFlows.java | 2 +- .../AnnotationGatewayProxyFactoryBean.java | 16 ++++++++++------ .../dsl/flows/IntegrationFlowTests.java | 14 ++++---------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationFlows.java b/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationFlows.java index 7921273449..7874fff9f1 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationFlows.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationFlows.java @@ -274,7 +274,7 @@ public final class IntegrationFlows { * on the provided service interface. *

A gateway proxy bean for provided service interface is registered under a name of * the {@link IntegrationFlow} bean plus {@code .gateway} suffix. - * @param serviceInterface the class with a + * @param serviceInterface the service interface class with an optional * {@link org.springframework.integration.annotation.MessagingGateway} annotation. * @return new {@link IntegrationFlowBuilder}. */ diff --git a/spring-integration-core/src/main/java/org/springframework/integration/gateway/AnnotationGatewayProxyFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/gateway/AnnotationGatewayProxyFactoryBean.java index 249fb6ba0c..859e5fd3f5 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/gateway/AnnotationGatewayProxyFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/gateway/AnnotationGatewayProxyFactoryBean.java @@ -23,6 +23,7 @@ import java.util.concurrent.Executor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.annotation.AnnotationUtils; import org.springframework.expression.Expression; import org.springframework.expression.common.LiteralExpression; import org.springframework.integration.annotation.AnnotationConstants; @@ -32,8 +33,9 @@ import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** - * A {@link GatewayProxyFactoryBean} extension for Java configuration, - * when service interface is marked with the {@link MessagingGateway} annotation. + * A {@link GatewayProxyFactoryBean} extension for Java configuration. + * The service interface may be marked with the {@link MessagingGateway} annotation. + * Otherwise the default state is applied. * * @author Artem Bilan * @@ -45,11 +47,13 @@ public class AnnotationGatewayProxyFactoryBean extends GatewayProxyFactoryBean { public AnnotationGatewayProxyFactoryBean(Class serviceInterface) { super(serviceInterface); - this.gatewayAttributes = AnnotatedElementUtils.getMergedAnnotationAttributes(serviceInterface, + AnnotationAttributes gatewayAttributes = AnnotatedElementUtils.getMergedAnnotationAttributes(serviceInterface, MessagingGateway.class.getName(), false, true); - Assert.notNull(this.gatewayAttributes, - "The Messaging Gateway interface must be annotated with the @MessagingGateway"); - + if (gatewayAttributes == null) { + gatewayAttributes = AnnotationUtils.getAnnotationAttributes( + AnnotationUtils.synthesizeAnnotation(MessagingGateway.class), false, true); + } + this.gatewayAttributes = gatewayAttributes; } @Override diff --git a/spring-integration-core/src/test/java/org/springframework/integration/dsl/flows/IntegrationFlowTests.java b/spring-integration-core/src/test/java/org/springframework/integration/dsl/flows/IntegrationFlowTests.java index b1894c92cc..880ec9ea10 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/dsl/flows/IntegrationFlowTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/dsl/flows/IntegrationFlowTests.java @@ -31,6 +31,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; import org.aopalliance.aop.Advice; import org.aopalliance.intercept.MethodInterceptor; @@ -423,11 +424,11 @@ public class IntegrationFlowTests { } @Autowired - private ErrorRecovererFlowGateway errorRecovererFlowGateway; + private Function errorRecovererFlowGateway; @Test public void testReplyChannelFromReplyMessage() { - assertEquals("foo", this.errorRecovererFlowGateway.testIt("foo")); + assertEquals("foo", this.errorRecovererFlowGateway.apply("foo")); } @Autowired @@ -719,7 +720,7 @@ public class IntegrationFlowTests { @Bean public IntegrationFlow errorRecovererFlow() { - return IntegrationFlows.from(ErrorRecovererFlowGateway.class) + return IntegrationFlows.from(Function.class) .handle((GenericHandler) (p, h) -> { throw new RuntimeException("intentional"); }, e -> e.advice(retryAdvice())) @@ -764,13 +765,6 @@ public class IntegrationFlowTests { } - @MessagingGateway - private interface ErrorRecovererFlowGateway { - - String testIt(String payload); - - } - @Service public static class GreetingService extends AbstractReplyProducingMessageHandler {