diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/MessagingGatewayRegistrar.java b/spring-integration-core/src/main/java/org/springframework/integration/config/MessagingGatewayRegistrar.java index 4eeed014b2..2ad7f7bee8 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/MessagingGatewayRegistrar.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/MessagingGatewayRegistrar.java @@ -24,11 +24,9 @@ import java.util.Map.Entry; import java.util.Set; import org.springframework.beans.factory.BeanDefinitionStoreException; -import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.beans.factory.support.BeanDefinitionRegistry; @@ -37,6 +35,7 @@ import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.context.annotation.Primary; +import org.springframework.core.ResolvableType; import org.springframework.core.type.AnnotationMetadata; import org.springframework.expression.common.LiteralExpression; import org.springframework.integration.annotation.AnnotationConstants; @@ -112,8 +111,8 @@ public class MessagingGatewayRegistrar implements ImportBeanDefinitionRegistrar Class serviceInterface = getServiceInterface((String) gatewayAttributes.get("serviceInterface"), beanFactory); BeanDefinitionBuilder gatewayProxyBuilder = - BeanDefinitionBuilder.genericBeanDefinition(GatewayProxyFactoryBean.class, - () -> new GatewayProxyFactoryBean(serviceInterface)); + BeanDefinitionBuilder.rootBeanDefinition(GatewayProxyFactoryBean.class, + () -> new GatewayProxyFactoryBean<>(serviceInterface)); if (hasDefaultHeaders || hasDefaultPayloadExpression) { BeanDefinitionBuilder methodMetadataBuilder = @@ -190,8 +189,9 @@ public class MessagingGatewayRegistrar implements ImportBeanDefinitionRegistrar gatewayProxyBuilder.addConstructorArgValue(serviceInterface); gatewayProxyBuilder.setPrimary(gatewayAttributes.containsKey(PRIMARY_ATTR)); - AbstractBeanDefinition beanDefinition = gatewayProxyBuilder.getBeanDefinition(); - beanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, serviceInterface); + RootBeanDefinition beanDefinition = (RootBeanDefinition) gatewayProxyBuilder.getBeanDefinition(); + beanDefinition.setTargetType( + ResolvableType.forClassWithGenerics(GatewayProxyFactoryBean.class, serviceInterface)); return new BeanDefinitionHolder(beanDefinition, id); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dsl/GatewayProxySpec.java b/spring-integration-core/src/main/java/org/springframework/integration/dsl/GatewayProxySpec.java index ed67e10d18..3b7b161ef2 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dsl/GatewayProxySpec.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dsl/GatewayProxySpec.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 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. @@ -16,7 +16,6 @@ package org.springframework.integration.dsl; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Executor; @@ -42,15 +41,16 @@ import org.springframework.messaging.MessageChannel; * * @author Artem Bilan * @author Gary Russell + * * @since 5.2 */ -public class GatewayProxySpec implements ComponentsRegistration { +public class GatewayProxySpec { - protected static final SpelExpressionParser PARSER = new SpelExpressionParser(); // NOSONAR - final + protected static final SpelExpressionParser PARSER = new SpelExpressionParser(); // NOSONAR - final protected final MessageChannel gatewayRequestChannel = new DirectChannel(); // NOSONAR - final - protected final GatewayProxyFactoryBean gatewayProxyFactoryBean; // NOSONAR - final + protected final GatewayProxyFactoryBean gatewayProxyFactoryBean; // NOSONAR - final protected final GatewayMethodMetadata gatewayMethodMetadata = new GatewayMethodMetadata(); // NOSONAR - final @@ -59,7 +59,7 @@ public class GatewayProxySpec implements ComponentsRegistration { private boolean populateGatewayMethodMetadata; protected GatewayProxySpec(Class serviceInterface) { - this.gatewayProxyFactoryBean = new AnnotationGatewayProxyFactoryBean(serviceInterface); + this.gatewayProxyFactoryBean = new AnnotationGatewayProxyFactoryBean<>(serviceInterface); this.gatewayProxyFactoryBean.setDefaultRequestChannel(this.gatewayRequestChannel); } @@ -145,7 +145,7 @@ public class GatewayProxySpec implements ComponentsRegistration { /** * Allows to specify how long this gateway will wait for the reply {@code Message} - * before returning. By default it will wait indefinitely. {@code null} is returned if + * before returning. By default, it will wait indefinitely. {@code null} is returned if * the gateway times out. Value is specified in milliseconds. * @param replyTimeout the timeout for replies in milliseconds. * @return current {@link GatewayProxySpec}. @@ -280,7 +280,7 @@ public class GatewayProxySpec implements ComponentsRegistration { return this.gatewayRequestChannel; } - GatewayProxyFactoryBean getGatewayProxyFactoryBean() { + GatewayProxyFactoryBean getGatewayProxyFactoryBean() { if (this.populateGatewayMethodMetadata) { this.gatewayMethodMetadata.setHeaderExpressions(this.headerExpressions); this.gatewayProxyFactoryBean.setGlobalMethodMetadata(this.gatewayMethodMetadata); @@ -288,10 +288,4 @@ public class GatewayProxySpec implements ComponentsRegistration { return this.gatewayProxyFactoryBean; } - @Override - public Map getComponentsToRegister() { - return Collections.singletonMap(this.gatewayProxyFactoryBean, this.gatewayProxyFactoryBean.getBeanName() - + ".gateway"); - } - } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowBeanPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowBeanPostProcessor.java index a712752fe8..c3566b22c2 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowBeanPostProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowBeanPostProcessor.java @@ -252,8 +252,7 @@ public class IntegrationFlowBeanPostProcessor registerComponent(component, subFlowBeanName, flowBeanName); targetIntegrationComponents.put(component, subFlowBeanName); } - else if (component instanceof AnnotationGatewayProxyFactoryBean) { - AnnotationGatewayProxyFactoryBean gateway = (AnnotationGatewayProxyFactoryBean) component; + else if (component instanceof AnnotationGatewayProxyFactoryBean gateway) { String gatewayId = entry.getValue(); if (gatewayId == null) { @@ -264,10 +263,8 @@ public class IntegrationFlowBeanPostProcessor } registerComponent(gateway, gatewayId, flowBeanName, - beanDefinition -> { - ((AbstractBeanDefinition) beanDefinition) - .setSource(new DescriptiveResource("" + gateway.getObjectType())); - }); + beanDefinition -> ((AbstractBeanDefinition) beanDefinition) + .setSource(new DescriptiveResource("" + gateway.getObjectType()))); targetIntegrationComponents.put(component, gatewayId); } @@ -431,7 +428,7 @@ public class IntegrationFlowBeanPostProcessor BeanDefinitionCustomizer... customizers) { AbstractBeanDefinition beanDefinition = - BeanDefinitionBuilder.genericBeanDefinition((Class) component.getClass(), () -> component) + BeanDefinitionBuilder.rootBeanDefinition((Class) component.getClass(), () -> component) .applyCustomizers(customizers) .getRawBeanDefinition(); 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 64b3e039f7..7ee6e06763 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 @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 the original author or authors. + * Copyright 2017-2022 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. @@ -39,18 +39,20 @@ import org.springframework.util.StringUtils; /** * A {@link GatewayProxyFactoryBean} extension for Java configuration. * The service interface may be marked with the {@link MessagingGateway} annotation. - * Otherwise the default state is applied. + * Otherwise, the default state is applied. + * + * @param the target gateway interface to build a proxy against. * * @author Artem Bilan * @author Gary Russell * * @since 5.0 */ -public class AnnotationGatewayProxyFactoryBean extends GatewayProxyFactoryBean { +public class AnnotationGatewayProxyFactoryBean extends GatewayProxyFactoryBean { private final AnnotationAttributes gatewayAttributes; - public AnnotationGatewayProxyFactoryBean(Class serviceInterface) { + public AnnotationGatewayProxyFactoryBean(Class serviceInterface) { super(serviceInterface); AnnotationAttributes annotationAttributes = diff --git a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayMessageHandler.java b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayMessageHandler.java index 3bfce1f45c..4293fe1447 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayMessageHandler.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 the original author or authors. + * Copyright 2016-2022 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. @@ -33,14 +33,14 @@ import org.springframework.messaging.MessageChannel; */ public class GatewayMessageHandler extends AbstractReplyProducingMessageHandler implements ManageableLifecycle { - private final GatewayProxyFactoryBean gatewayProxyFactoryBean; + private final GatewayProxyFactoryBean gatewayProxyFactoryBean; - private RequestReplyExchanger exchanger; + private volatile RequestReplyExchanger exchanger; private volatile boolean running; public GatewayMessageHandler() { - this.gatewayProxyFactoryBean = new GatewayProxyFactoryBean(); + this.gatewayProxyFactoryBean = new GatewayProxyFactoryBean<>(); } public void setRequestChannel(MessageChannel requestChannel) { 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 d8537e83fc..1ba8048069 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 @@ -99,20 +99,22 @@ import reactor.core.publisher.Mono; * to * perform type conversions when necessary (thanks to Jon Schneider's contribution and suggestion in INT-1230). * + * @param the target gateway interface to build a proxy against. + * * @author Mark Fisher * @author Oleg Zhurakousky * @author Gary Russell * @author Artem Bilan */ -public class GatewayProxyFactoryBean extends AbstractEndpoint - implements TrackableComponent, FactoryBean, MethodInterceptor, BeanClassLoaderAware, +public class GatewayProxyFactoryBean extends AbstractEndpoint + implements TrackableComponent, FactoryBean, MethodInterceptor, BeanClassLoaderAware, IntegrationManagement { private final Object initializationMonitor = new Object(); private final Map gatewayMap = new HashMap<>(); - private final Class serviceInterface; + private final Class serviceInterface; private final Set havePayloadExpressions = new HashSet<>(); @@ -140,7 +142,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); - private Object serviceProxy; + private T serviceProxy; private AsyncTaskExecutor asyncExecutor = new SimpleAsyncTaskExecutor(); @@ -165,11 +167,12 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint * If none is set, it will fall back to the default service interface type, * {@link RequestReplyExchanger}, upon initialization. */ + @SuppressWarnings("unchecked") public GatewayProxyFactoryBean() { - this.serviceInterface = RequestReplyExchanger.class; + this((Class) RequestReplyExchanger.class); } - public GatewayProxyFactoryBean(Class serviceInterface) { + public GatewayProxyFactoryBean(Class serviceInterface) { Assert.notNull(serviceInterface, "'serviceInterface' must not be null"); Assert.isTrue(serviceInterface.isInterface(), "'serviceInterface' must be an interface"); this.serviceInterface = serviceInterface; @@ -449,6 +452,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint } @Override + @SuppressWarnings("unchecked") protected void onInit() { synchronized (this.initializationMonitor) { if (this.initialized) { @@ -464,7 +468,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint ProxyFactory gatewayProxyFactory = new ProxyFactory(this.serviceInterface, this); gatewayProxyFactory.addAdvice(new DefaultMethodInvokingMethodInterceptor()); - this.serviceProxy = gatewayProxyFactory.getProxy(this.beanClassLoader); + this.serviceProxy = (T) gatewayProxyFactory.getProxy(this.beanClassLoader); this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(beanFactory); this.initialized = true; } @@ -489,7 +493,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint } @Override - public Object getObject() { + public T getObject() { if (this.serviceProxy == null) { this.onInit(); Assert.notNull(this.serviceProxy, "failed to initialize proxy"); diff --git a/spring-integration-core/src/main/java/org/springframework/integration/graph/IntegrationGraphServer.java b/spring-integration-core/src/main/java/org/springframework/integration/graph/IntegrationGraphServer.java index cae3809581..85eeeb139f 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/graph/IntegrationGraphServer.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/graph/IntegrationGraphServer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 the original author or authors. + * Copyright 2016-2022 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. @@ -236,9 +236,10 @@ public class IntegrationGraphServer implements ApplicationContextAware, Applicat .peek(nodes::add) .forEach(gatewayNode -> producerLink(links, channelNodes, gatewayNode)); - Map gpfbs = getBeansOfType(GatewayProxyFactoryBean.class); + @SuppressWarnings({ "rawtypes", "unchecked"}) + Map> gpfbs = (Map) getBeansOfType(GatewayProxyFactoryBean.class); - for (Entry entry : gpfbs.entrySet()) { + for (Entry> entry : gpfbs.entrySet()) { entry.getValue() .getGateways() .entrySet() diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/ChainParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/ChainParserTests.java index 93d009dda4..1a12626bcd 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/ChainParserTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/ChainParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2022 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. @@ -392,8 +392,8 @@ public class ChainParserTests { .isTrue(); assertThat(this.beanFactory.containsBean("subComponentsIdSupport1$child.gatewayWithinChain.handler")).isTrue(); //INT-3117 - GatewayProxyFactoryBean gatewayProxyFactoryBean = this.beanFactory.getBean("&subComponentsIdSupport1$child" + - ".gatewayWithinChain.handler", + GatewayProxyFactoryBean gatewayProxyFactoryBean = + this.beanFactory.getBean("&subComponentsIdSupport1$child.gatewayWithinChain.handler", GatewayProxyFactoryBean.class); assertThat(TestUtils.getPropertyValue(gatewayProxyFactoryBean, "defaultRequestChannelName")) .isEqualTo("strings"); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/GatewayParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/GatewayParserTests.java index c3dfae34ca..59421a5a1b 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/GatewayParserTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/GatewayParserTests.java @@ -36,11 +36,12 @@ import org.mockito.ArgumentMatchers; import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.factory.BeanNameAware; -import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.ResolvableType; import org.springframework.core.log.LogAccessor; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.expression.Expression; @@ -111,7 +112,7 @@ public class GatewayParserTests { assertThat(result.getPayload()).isEqualTo("fiz"); assertThat(result.getHeaders().get("foo")).isEqualTo("bar"); assertThat(result.getHeaders().get("baz")).isEqualTo("qux"); - GatewayProxyFactoryBean fb = context.getBean("&methodOverride", GatewayProxyFactoryBean.class); + GatewayProxyFactoryBean fb = context.getBean("&methodOverride", GatewayProxyFactoryBean.class); assertThat(TestUtils.getPropertyValue(fb, "defaultRequestTimeout", Expression.class).getValue()) .isEqualTo(1000L); assertThat(TestUtils.getPropertyValue(fb, "defaultReplyTimeout", Expression.class).getValue()).isEqualTo(2000L); @@ -198,17 +199,17 @@ public class GatewayParserTests { @Test public void testFactoryBeanObjectTypeWithServiceInterface() { ConfigurableListableBeanFactory beanFactory = ((GenericApplicationContext) context).getBeanFactory(); - Object attribute = - beanFactory.getMergedBeanDefinition("&oneWay").getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE); - assertThat(attribute).isEqualTo(TestService.class); + BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition("&oneWay"); + ResolvableType resolvableType = beanDefinition.getResolvableType(); + assertThat(resolvableType.getGeneric(0).getRawClass()).isEqualTo(TestService.class); } @Test public void testFactoryBeanObjectTypeWithNoServiceInterface() { ConfigurableListableBeanFactory beanFactory = ((GenericApplicationContext) context).getBeanFactory(); - Object attribute = - beanFactory.getMergedBeanDefinition("&defaultConfig").getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE); - assertThat(attribute).isEqualTo(RequestReplyExchanger.class); + BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition("&defaultConfig"); + ResolvableType resolvableType = beanDefinition.getResolvableType(); + assertThat(resolvableType.getGeneric(0).getRawClass()).isEqualTo(RequestReplyExchanger.class); } @Test 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 fd924b8c24..3dcfcf8364 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 @@ -34,7 +34,7 @@ import java.util.function.Supplier; import org.aopalliance.aop.Advice; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; -import org.junit.After; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanCreationException; @@ -527,7 +527,7 @@ public class IntegrationFlowTests { public void testStandardIntegrationFlowLifecycle() { this.controlBusFlow.stop(); - GatewayProxyFactoryBean controlBusGateway = + GatewayProxyFactoryBean controlBusGateway = this.beanFactory.getBean("&controlBusGateway", GatewayProxyFactoryBean.class); assertThat(controlBusGateway.isRunning()).isFalse(); Lifecycle controlBus = this.beanFactory.getBean("controlBus", Lifecycle.class); @@ -540,7 +540,7 @@ public class IntegrationFlowTests { } - @After + @AfterEach public void cleanUpList() { outputStringList.clear(); } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/dsl/gateway/GatewayDslTests.java b/spring-integration-core/src/test/java/org/springframework/integration/dsl/gateway/GatewayDslTests.java index 255db9a2ac..efb4b057d0 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/dsl/gateway/GatewayDslTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/dsl/gateway/GatewayDslTests.java @@ -114,7 +114,7 @@ public class GatewayDslTests { @Autowired @Qualifier("&functionGateway.gateway") - private GatewayProxyFactoryBean functionGatewayFactoryBean; + private GatewayProxyFactoryBean functionGatewayFactoryBean; @Test void testHeadersFromFunctionGateway() { @@ -154,7 +154,7 @@ public class GatewayDslTests { @Autowired @Qualifier("&routingGateway") - private GatewayProxyFactoryBean routingGatewayProxy; + private GatewayProxyFactoryBean routingGatewayProxy; @Test void testRoutingGateway() { diff --git a/spring-integration-core/src/test/java/org/springframework/integration/gateway/AsyncGatewayTests.java b/spring-integration-core/src/test/java/org/springframework/integration/gateway/AsyncGatewayTests.java index 6b2a5afb95..e0db108aba 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/gateway/AsyncGatewayTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/gateway/AsyncGatewayTests.java @@ -63,12 +63,12 @@ public class AsyncGatewayTests { public void futureWithMessageReturned() throws Exception { QueueChannel requestChannel = new QueueChannel(); startResponder(requestChannel); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); Future> f = service.returnMessage("foo"); Object result = f.get(10000, TimeUnit.MILLISECONDS); assertThat(result).isNotNull(); @@ -86,12 +86,12 @@ public class AsyncGatewayTests { } }; - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(channel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); Future> f = service.returnMessage("foo"); assertThatExceptionOfType(ExecutionException.class) @@ -104,12 +104,12 @@ public class AsyncGatewayTests { QueueChannel requestChannel = new QueueChannel(); addThreadEnricher(requestChannel); startResponder(requestChannel); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); CompletableFuture> f = service.returnMessageListenable("foo"); long start = System.currentTimeMillis(); final AtomicReference> result = new AtomicReference<>(); @@ -133,12 +133,12 @@ public class AsyncGatewayTests { QueueChannel requestChannel = new QueueChannel(); addThreadEnricher(requestChannel); startResponder(requestChannel); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); CustomFuture f = service.returnCustomFuture("foo"); String result = f.get(10000, TimeUnit.MILLISECONDS); assertThat(result).isEqualTo("foobar"); @@ -150,7 +150,7 @@ public class AsyncGatewayTests { QueueChannel requestChannel = new QueueChannel(); addThreadEnricher(requestChannel); startResponder(requestChannel); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); @@ -158,7 +158,7 @@ public class AsyncGatewayTests { proxyFactory.setAsyncExecutor(null); // Not async - user flow returns Future proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); CustomFuture f = (CustomFuture) service.returnCustomFutureWithTypeFuture("foo"); String result = f.get(10000, TimeUnit.MILLISECONDS); assertThat(result).isEqualTo("foobar"); @@ -182,12 +182,12 @@ public class AsyncGatewayTests { public void futureWithPayloadReturned() throws Exception { QueueChannel requestChannel = new QueueChannel(); startResponder(requestChannel); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); Future f = service.returnString("foo"); Object result = f.get(10000, TimeUnit.MILLISECONDS); assertThat(result).isNotNull(); @@ -198,12 +198,12 @@ public class AsyncGatewayTests { public void futureWithWildcardReturned() throws Exception { QueueChannel requestChannel = new QueueChannel(); startResponder(requestChannel); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); Future f = service.returnSomething("foo"); Object result = f.get(10000, TimeUnit.MILLISECONDS); assertThat(result instanceof String).isTrue(); @@ -212,12 +212,12 @@ public class AsyncGatewayTests { @Test public void futureVoid() throws Exception { - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(new NullChannel()); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); Future f = service.asyncSendAndForget("test1"); Object result = f.get(10, TimeUnit.SECONDS); assertThat(result).isNull(); @@ -252,13 +252,13 @@ public class AsyncGatewayTests { ReflectionUtils.rethrowRuntimeException(ex); } }).start(); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.setAsyncExecutor(null); proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); Future f = service.sendAndReceiveFutureVoid("test"); readyForReplyLatch.countDown(); Object result = f.get(10, TimeUnit.SECONDS); @@ -269,12 +269,12 @@ public class AsyncGatewayTests { public void monoWithMessageReturned() { QueueChannel requestChannel = new QueueChannel(); startResponder(requestChannel); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.setBeanName("testGateway"); proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); Mono> mono = service.returnMessagePromise("foo"); Object result = mono.block(Duration.ofSeconds(10)); assertThat(((Message) result).getPayload()).isEqualTo("foobar"); @@ -284,12 +284,12 @@ public class AsyncGatewayTests { public void monoWithPayloadReturned() { QueueChannel requestChannel = new QueueChannel(); startResponder(requestChannel); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.setBeanName("testGateway"); proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); Mono mono = service.returnStringPromise("foo"); Object result = mono.block(Duration.ofSeconds(10)); assertThat(result).isEqualTo("foobar"); @@ -299,12 +299,12 @@ public class AsyncGatewayTests { public void monoWithWildcardReturned() { QueueChannel requestChannel = new QueueChannel(); startResponder(requestChannel); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.setBeanName("testGateway"); proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); Mono mono = service.returnSomethingPromise("foo"); Object result = mono.block(Duration.ofSeconds(10)); assertThat(result).isNotNull(); @@ -315,12 +315,12 @@ public class AsyncGatewayTests { public void monoWithConsumer() { QueueChannel requestChannel = new QueueChannel(); startResponder(requestChannel); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.setBeanName("testGateway"); proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); Mono mono = service.returnStringPromise("foo"); StepVerifier.create(mono) @@ -330,12 +330,12 @@ public class AsyncGatewayTests { @Test public void monoVoid() throws InterruptedException { - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestEchoService.class); proxyFactory.setDefaultRequestChannel(new NullChannel()); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestEchoService service = (TestEchoService) proxyFactory.getObject(); + TestEchoService service = proxyFactory.getObject(); Mono mono = service.monoVoid("test1"); CountDownLatch emptyMonoLatch = new CountDownLatch(1); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInterfaceTests.java b/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInterfaceTests.java index d34430ca74..cf58f957be 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInterfaceTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInterfaceTests.java @@ -41,13 +41,16 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.springframework.aop.support.AopUtils; -import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.Primary; @@ -55,6 +58,7 @@ import org.springframework.context.annotation.Profile; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.SimpleAsyncTaskExecutor; +import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.expression.Expression; import org.springframework.expression.common.LiteralExpression; import org.springframework.integration.annotation.AnnotationConstants; @@ -103,7 +107,7 @@ public class GatewayInterfaceTests { private static final String IGNORE_HEADER = "ignoreHeader"; @Autowired - private BeanFactory beanFactory; + private ListableBeanFactory beanFactory; @Autowired private Int2634Gateway int2634Gateway; @@ -116,11 +120,11 @@ public class GatewayInterfaceTests { @Autowired @Qualifier("&gatewayInterfaceTests$ExecGateway") - private GatewayProxyFactoryBean execGatewayFB; + private GatewayProxyFactoryBean execGatewayFB; @Autowired @Qualifier("&gatewayInterfaceTests$NoExecGateway") - private GatewayProxyFactoryBean noExecGatewayFB; + private GatewayProxyFactoryBean noExecGatewayFB; @Autowired private SimpleAsyncTaskExecutor exec; @@ -136,7 +140,7 @@ public class GatewayInterfaceTests { @Autowired @Qualifier("&annotationGatewayProxyFactoryBean") - private GatewayProxyFactoryBean annotationGatewayProxyFactoryBean; + private GatewayProxyFactoryBean annotationGatewayProxyFactoryBean; @Autowired private MessageChannel gatewayChannel; @@ -319,7 +323,7 @@ public class GatewayInterfaceTests { channel.subscribe(handler); Bar bar = ac.getBean(Bar.class); assertThat(ac.getBean(Bar.class)).isSameAs(bar); - GatewayProxyFactoryBean fb = new GatewayProxyFactoryBean(Bar.class); + GatewayProxyFactoryBean fb = new GatewayProxyFactoryBean<>(Bar.class); DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); bf.registerSingleton("requestChannelBar", channel); bf.registerSingleton("requestChannelBaz", channel); @@ -346,7 +350,7 @@ public class GatewayInterfaceTests { @Test public void testWithServiceAsNotAnInterface() { - assertThatIllegalArgumentException().isThrownBy(() -> new GatewayProxyFactoryBean(NotAnInterface.class)); + assertThatIllegalArgumentException().isThrownBy(() -> new GatewayProxyFactoryBean<>(NotAnInterface.class)); } @Test @@ -399,7 +403,7 @@ public class GatewayInterfaceTests { /* * Tests use current thread in payload and reply has the thread that actually - * performed the send() on gatewayThreadChannel. + * performed the 'send()' on gatewayThreadChannel. */ @Test @SuppressWarnings("deprecation") @@ -674,12 +678,13 @@ public class GatewayInterfaceTests { @Bean - public GatewayProxyFactoryBean annotationGatewayProxyFactoryBean() { - return new AnnotationGatewayProxyFactoryBean(GatewayByAnnotationGPFB.class); + public GatewayProxyFactoryBean annotationGatewayProxyFactoryBean() { + return new AnnotationGatewayProxyFactoryBean<>(GatewayByAnnotationGPFB.class); } + @Conditional(GatewayByAnnotationGPFBCondition.class) @Bean - PrimaryGateway notPrimaryGatewayInstance() { + PrimaryGateway notPrimaryGatewayInstance(GatewayByAnnotationGPFB annotationGPFB) { return payload -> { }; } @@ -792,4 +797,13 @@ public class GatewayInterfaceTests { } + public static class GatewayByAnnotationGPFBCondition implements Condition { + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + return context.getBeanFactory().getBeanNamesForType(GatewayByAnnotationGPFB.class).length > 0; + } + + } + } 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..cccac95309 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -77,12 +77,12 @@ public class GatewayProxyFactoryBeanTests { public void testRequestReplyWithAnonymousChannel() { QueueChannel requestChannel = new QueueChannel(); startResponder(requestChannel); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.setBeanName("testGateway"); proxyFactory.afterPropertiesSet(); - TestService service = (TestService) proxyFactory.getObject(); + TestService service = proxyFactory.getObject(); String result = service.requestReply("foo"); assertThat(result).isEqualTo("foobar"); } @@ -104,7 +104,7 @@ public class GatewayProxyFactoryBeanTests { }; stringToByteConverter = spy(stringToByteConverter); cs.addConverter(stringToByteConverter); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestService.class); DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); bf.registerSingleton(IntegrationUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME, cs); @@ -112,7 +112,7 @@ public class GatewayProxyFactoryBeanTests { proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.afterPropertiesSet(); - TestService service = (TestService) proxyFactory.getObject(); + TestService service = proxyFactory.getObject(); byte[] result = service.requestReplyInBytes("foo"); assertThat(result.length).isEqualTo(6); Mockito.verify(stringToByteConverter, Mockito.times(1)).convert(Mockito.any(String.class)); @@ -121,12 +121,12 @@ public class GatewayProxyFactoryBeanTests { @Test public void testOneWay() { final QueueChannel requestChannel = new QueueChannel(); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestService service = (TestService) proxyFactory.getObject(); + TestService service = proxyFactory.getObject(); service.oneWay("test"); Message message = requestChannel.receive(1000); assertThat(message).isNotNull(); @@ -145,12 +145,12 @@ public class GatewayProxyFactoryBeanTests { handler.setBeanFactory(beanFactory); handler.afterPropertiesSet(); requestChannel.subscribe(handler); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(beanFactory); proxyFactory.afterPropertiesSet(); - TestService service = (TestService) proxyFactory.getObject(); + TestService service = proxyFactory.getObject(); service.oneWay("test"); Message message = nullChannel.receive(1000); assertThat(message) @@ -163,13 +163,13 @@ public class GatewayProxyFactoryBeanTests { public void testSolicitResponse() { QueueChannel replyChannel = new QueueChannel(); replyChannel.send(new GenericMessage<>("foo")); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestService.class); proxyFactory.setDefaultRequestChannel(new DirectChannel()); proxyFactory.setDefaultReplyChannel(replyChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestService service = (TestService) proxyFactory.getObject(); + TestService service = proxyFactory.getObject(); String result = service.solicitResponse(); assertThat(result).isNotNull(); assertThat(result).isEqualTo("foo"); @@ -179,12 +179,12 @@ public class GatewayProxyFactoryBeanTests { public void testReceiveMessage() { QueueChannel replyChannel = new QueueChannel(); replyChannel.send(new GenericMessage<>("foo")); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestService.class); proxyFactory.setDefaultReplyChannel(replyChannel); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestService service = (TestService) proxyFactory.getObject(); + TestService service = proxyFactory.getObject(); Message message = service.getMessage(); assertThat(message).isNotNull(); assertThat(message.getPayload()).isEqualTo("foo"); @@ -200,13 +200,13 @@ public class GatewayProxyFactoryBeanTests { QueueChannel requestChannel = new QueueChannel(); startResponder(requestChannel); FluxMessageChannel replyChannel = new FluxMessageChannel(); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setDefaultReplyChannel(replyChannel); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestService service = (TestService) proxyFactory.getObject(); + TestService service = proxyFactory.getObject(); String result = service.requestReply("test"); assertThat(result).isEqualTo("testbar"); @@ -220,12 +220,12 @@ public class GatewayProxyFactoryBeanTests { GenericMessage reply = new GenericMessage<>(input.getPayload() + "456"); ((MessageChannel) input.getHeaders().getReplyChannel()).send(reply); }).start(); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestService service = (TestService) proxyFactory.getObject(); + TestService service = proxyFactory.getObject(); Integer result = service.requestReplyWithIntegers(123); assertThat(result).isEqualTo(123456); } @@ -291,12 +291,12 @@ public class GatewayProxyFactoryBeanTests { public void testMessageAsMethodArgument() { QueueChannel requestChannel = new QueueChannel(); startResponder(requestChannel); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestService service = (TestService) proxyFactory.getObject(); + TestService service = proxyFactory.getObject(); String result = service.requestReplyWithMessageParameter(new GenericMessage<>("foo")); assertThat(result).isEqualTo("foobar"); } @@ -305,12 +305,12 @@ public class GatewayProxyFactoryBeanTests { public void testNoArgMethodWithPayloadAnnotation() { QueueChannel requestChannel = new QueueChannel(); startResponder(requestChannel); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestService service = (TestService) proxyFactory.getObject(); + TestService service = proxyFactory.getObject(); String result = service.requestReplyWithPayloadAnnotation(); assertThat(result).isEqualTo("requestReplyWithPayloadAnnotation0bar"); @@ -329,12 +329,12 @@ public class GatewayProxyFactoryBeanTests { GenericMessage reply = new GenericMessage<>(input.getPayload() + "bar"); ((MessageChannel) input.getHeaders().getReplyChannel()).send(reply); }).start(); - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestService.class); proxyFactory.setDefaultRequestChannel(requestChannel); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestService service = (TestService) proxyFactory.getObject(); + TestService service = proxyFactory.getObject(); Message result = service.requestReplyWithMessageReturnValue("foo"); assertThat(result.getPayload()).isEqualTo("foobar"); } @@ -342,12 +342,12 @@ public class GatewayProxyFactoryBeanTests { @Test public void testServiceMustBeInterface() { assertThatIllegalArgumentException() - .isThrownBy(() -> new GatewayProxyFactoryBean(String.class)); + .isThrownBy(() -> new GatewayProxyFactoryBean<>(String.class)); } @Test public void testProxiedToStringMethod() { - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestService.class); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean<>(TestService.class); proxyFactory.setDefaultRequestChannel(new DirectChannel()); proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); @@ -359,7 +359,8 @@ public class GatewayProxyFactoryBeanTests { @Test public void testCheckedExceptionRethrownAsIs() { - GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(TestExceptionThrowingInterface.class); + GatewayProxyFactoryBean proxyFactory = + new GatewayProxyFactoryBean<>(TestExceptionThrowingInterface.class); DirectChannel channel = new DirectChannel(); EventDrivenConsumer consumer = new EventDrivenConsumer(channel, new MessageHandler() { @@ -375,7 +376,7 @@ public class GatewayProxyFactoryBeanTests { proxyFactory.setBeanName("testGateway"); proxyFactory.setBeanFactory(mock(BeanFactory.class)); proxyFactory.afterPropertiesSet(); - TestExceptionThrowingInterface proxy = (TestExceptionThrowingInterface) proxyFactory.getObject(); + TestExceptionThrowingInterface proxy = proxyFactory.getObject(); assertThatExceptionOfType(TestException.class) .isThrownBy(() -> proxy.throwCheckedException("test")); } @@ -391,7 +392,7 @@ public class GatewayProxyFactoryBeanTests { @Test public void testProgrammaticWiring() { - GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean(TestEchoService.class); + GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean<>(TestEchoService.class); gpfb.setBeanFactory(mock(BeanFactory.class)); QueueChannel drc = new QueueChannel(); gpfb.setDefaultRequestChannel(drc); @@ -400,7 +401,7 @@ public class GatewayProxyFactoryBeanTests { meta.setHeaderExpressions(Collections.singletonMap("foo", new LiteralExpression("bar"))); gpfb.setGlobalMethodMetadata(meta); gpfb.afterPropertiesSet(); - ((TestEchoService) gpfb.getObject()).echo("foo"); + gpfb.getObject().echo("foo"); Message message = drc.receive(0); assertThat(message).isNotNull(); String bar = (String) message.getHeaders().get("foo"); @@ -410,7 +411,7 @@ public class GatewayProxyFactoryBeanTests { @Test public void testIdHeaderOverrideHeaderExpression() { - GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean(); + GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean<>(); gpfb.setBeanFactory(mock(BeanFactory.class)); GatewayMethodMetadata meta = new GatewayMethodMetadata(); @@ -424,7 +425,8 @@ public class GatewayProxyFactoryBeanTests { @Test public void testIdHeaderOverrideGatewayHeaderAnnotation() { - GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean(HeadersOverwriteService.class); + GatewayProxyFactoryBean gpfb = + new GatewayProxyFactoryBean<>(HeadersOverwriteService.class); gpfb.setBeanFactory(mock(BeanFactory.class)); assertThatExceptionOfType(BeanInitializationException.class) @@ -434,7 +436,7 @@ public class GatewayProxyFactoryBeanTests { @Test public void testTimeStampHeaderOverrideParamHeaderAnnotation() { - GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean(HeadersParamService.class); + GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean<>(HeadersParamService.class); gpfb.setBeanFactory(mock(BeanFactory.class)); assertThatExceptionOfType(BeanInitializationException.class) @@ -487,7 +489,7 @@ public class GatewayProxyFactoryBeanTests { @Test public void testOverriddenMethod() { - GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean(InheritChild.class); + GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean<>(InheritChild.class); gpfb.setBeanFactory(mock(BeanFactory.class)); gpfb.afterPropertiesSet(); Map gateways = gpfb.getGateways(); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayProxyMessageMappingTests.java b/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayProxyMessageMappingTests.java index ab2a02d5ad..f581447b5b 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayProxyMessageMappingTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayProxyMessageMappingTests.java @@ -51,7 +51,7 @@ public class GatewayProxyMessageMappingTests { @BeforeEach public void initializeGateway() { - GatewayProxyFactoryBean factoryBean = new GatewayProxyFactoryBean(TestGateway.class); + GatewayProxyFactoryBean factoryBean = new GatewayProxyFactoryBean<>(TestGateway.class); factoryBean.setDefaultRequestChannel(channel); factoryBean.setBeanName("testGateway"); GenericApplicationContext context = new GenericApplicationContext(); @@ -60,7 +60,7 @@ public class GatewayProxyMessageMappingTests { context.refresh(); factoryBean.setBeanFactory(context); factoryBean.afterPropertiesSet(); - this.gateway = (TestGateway) factoryBean.getObject(); + this.gateway = factoryBean.getObject(); } @Test diff --git a/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayXmlAndAnnotationTests.java b/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayXmlAndAnnotationTests.java index 99c4534e9e..e61c0179ce 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayXmlAndAnnotationTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayXmlAndAnnotationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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. @@ -22,27 +22,26 @@ import java.lang.reflect.Method; import java.util.Map; import java.util.Map.Entry; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.expression.Expression; import org.springframework.integration.annotation.Gateway; import org.springframework.integration.test.util.TestUtils; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; /** * @author Gary Russell + * @author Artem Bilan + * * @since 2.2 * */ -@ContextConfiguration -@RunWith(SpringJUnit4ClassRunner.class) +@SpringJUnitConfig public class GatewayXmlAndAnnotationTests { @Autowired - GatewayProxyFactoryBean gatewayProxyFactoryBean; + GatewayProxyFactoryBean gatewayProxyFactoryBean; @Test public void test() { @@ -78,6 +77,7 @@ public class GatewayXmlAndAnnotationTests { } public interface AGateway { + @Gateway String annotationShouldntOverrideDefault(String foo); @@ -88,5 +88,7 @@ public class GatewayXmlAndAnnotationTests { String annotationShouldOverrideDefaultToInfinity(String foo); String explicitTimeoutShouldOverrideDefault(String foo); + } + } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/handler/AsyncHandlerTests.java b/spring-integration-core/src/test/java/org/springframework/integration/handler/AsyncHandlerTests.java index 697e1302f2..b9a099cdca 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/handler/AsyncHandlerTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/handler/AsyncHandlerTests.java @@ -215,15 +215,15 @@ public class AsyncHandlerTests { } @Test - public void testGateway() throws Exception { + public void testGateway() { this.whichTest = 0; - GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean(Foo.class); + GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean<>(Foo.class); gpfb.setBeanFactory(mock(BeanFactory.class)); DirectChannel input = new DirectChannel(); gpfb.setDefaultRequestChannel(input); gpfb.setDefaultReplyTimeout(10000L); gpfb.afterPropertiesSet(); - Foo foo = (Foo) gpfb.getObject(); + Foo foo = gpfb.getObject(); this.handler.setOutputChannel(null); EventDrivenConsumer consumer = new EventDrivenConsumer(input, this.handler); consumer.afterPropertiesSet(); @@ -234,15 +234,15 @@ public class AsyncHandlerTests { } @Test - public void testGatewayWithException() throws Exception { + public void testGatewayWithException() { this.whichTest = 0; - GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean(Foo.class); + GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean<>(Foo.class); gpfb.setBeanFactory(mock(BeanFactory.class)); DirectChannel input = new DirectChannel(); gpfb.setDefaultRequestChannel(input); gpfb.setDefaultReplyTimeout(10000L); gpfb.afterPropertiesSet(); - Foo foo = (Foo) gpfb.getObject(); + Foo foo = gpfb.getObject(); this.handler.setOutputChannel(null); EventDrivenConsumer consumer = new EventDrivenConsumer(input, this.handler); consumer.afterPropertiesSet(); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/handler/MethodInvokingMessageProcessorTests.java b/spring-integration-core/src/test/java/org/springframework/integration/handler/MethodInvokingMessageProcessorTests.java index 2206288e97..9ff4dd79e0 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/handler/MethodInvokingMessageProcessorTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/handler/MethodInvokingMessageProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -623,7 +623,7 @@ public class MethodInvokingMessageProcessorTests { @Test public void gatewayTest() throws Exception { - GatewayProxyFactoryBean gwFactoryBean = new GatewayProxyFactoryBean(); + GatewayProxyFactoryBean gwFactoryBean = new GatewayProxyFactoryBean<>(); gwFactoryBean.setBeanFactory(mock(BeanFactory.class)); gwFactoryBean.afterPropertiesSet(); Object target = gwFactoryBean.getObject(); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/support/management/micrometer/MicrometerMetricsTests.java b/spring-integration-core/src/test/java/org/springframework/integration/support/management/micrometer/MicrometerMetricsTests.java index 66a14cf275..8e235cc9ce 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/support/management/micrometer/MicrometerMetricsTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/support/management/micrometer/MicrometerMetricsTests.java @@ -345,8 +345,8 @@ public class MicrometerMetricsTests { } @Bean - public GatewayProxyFactoryBean gates() { - GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean(Gate.class); + public GatewayProxyFactoryBean gates() { + GatewayProxyFactoryBean gpfb = new GatewayProxyFactoryBean<>(Gate.class); gpfb.setDefaultRequestChannelName("nullChannel"); return gpfb; } diff --git a/spring-integration-core/src/test/kotlin/org/springframework/integration/function/FunctionsTests.kt b/spring-integration-core/src/test/kotlin/org/springframework/integration/function/FunctionsTests.kt index 880e94ed0c..4a566492f6 100644 --- a/spring-integration-core/src/test/kotlin/org/springframework/integration/function/FunctionsTests.kt +++ b/spring-integration-core/src/test/kotlin/org/springframework/integration/function/FunctionsTests.kt @@ -21,6 +21,8 @@ import assertk.assertions.* import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Test +import org.springframework.beans.factory.BeanFactory +import org.springframework.beans.factory.ListableBeanFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Qualifier import org.springframework.context.annotation.Bean @@ -130,7 +132,7 @@ class FunctionsTests { @Autowired @Qualifier("&monoFunctionGateway.gateway") - private lateinit var monoFunctionGateway: GatewayProxyFactoryBean + private lateinit var monoFunctionGateway: GatewayProxyFactoryBean<*> @Test fun `verify Mono gateway`() { diff --git a/src/reference/asciidoc/gateway.adoc b/src/reference/asciidoc/gateway.adoc index 3435260a4e..8b28162cff 100644 --- a/src/reference/asciidoc/gateway.adoc +++ b/src/reference/asciidoc/gateway.adoc @@ -312,7 +312,7 @@ public interface TestGateway { IMPORTANT: Similarly to the XML version, when Spring Integration discovers these annotations during a component scan, it creates the `proxy` implementation with its messaging infrastructure. To perform this scan and register the `BeanDefinition` in the application context, add the `@IntegrationComponentScan` annotation to a `@Configuration` class. The standard `@ComponentScan` infrastructure does not deal with interfaces. -Consequently, we introduced the custom `@IntegrationComponentScan` logic to fine the `@MessagingGateway` annotation on the interfaces and register `GatewayProxyFactoryBean` instances for them. +Consequently, we introduced the custom `@IntegrationComponentScan` logic to find the `@MessagingGateway` annotation on the interfaces and register `GatewayProxyFactoryBean` instances for them. See also <<./configuration.adoc#annotations,Annotation Support>>. Along with the `@MessagingGateway` annotation you can mark a service interface with the `@Profile` annotation to avoid the bean creation, if such a profile is not active. @@ -857,7 +857,7 @@ Consequently, if you do not explicitly set the `reply-timeout`, your gateway met So, to make sure you analyze your flow and if there is even a remote possibility of one of these scenarios to occur, you should set the `reply-timeout` attribute to a "'safe'" value. Even better, you can set the `requires-reply` attribute of the downstream component to 'true' to ensure a timely response, as produced by the throwing of an exception as soon as that downstream component returns null internally. However, you should also realize that there are some scenarios (see <>) where `reply-timeout` does not help. -That means it is also important to analyze your message flow and decide when to use a synchronous gateway rather than an asynchrnous gateway. +That means it is also important to analyze your message flow and decide when to use a synchronous gateway rather than an asynchronous gateway. As <>, the latter case is a matter of defining gateway methods that return `Future` instances. Then you are guaranteed to receive that return value, and you have more granular control over the results of the invocation. Also, when dealing with a router, you should remember that setting the `resolution-required` attribute to 'true' results in an exception thrown by the router if it can not resolve a particular channel.