diff --git a/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationObjectSupport.java b/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationObjectSupport.java index bbe8d58ccf..4d3e497d4e 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationObjectSupport.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationObjectSupport.java @@ -18,7 +18,6 @@ package org.springframework.integration.context; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanInitializationException; @@ -40,6 +39,7 @@ import org.springframework.util.Assert; * dependency injection. * * @author Mark Fisher + * @author Oleg Zhurakousky */ public abstract class IntegrationObjectSupport implements BeanNameAware, NamedComponent, BeanFactoryAware, InitializingBean { @@ -79,6 +79,11 @@ public abstract class IntegrationObjectSupport implements BeanNameAware, NamedCo } public final void afterPropertiesSet() { + if (beanFactory != null){ + if (this.getBeanFactory().containsBean(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME)){ + this.setConversionService(this.getBeanFactory().getBean(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); + } + } try { this.onInit(); } 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 ca99f989db..6cefa64f2b 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 @@ -29,8 +29,11 @@ import org.springframework.aop.support.AopUtils; import org.springframework.beans.SimpleTypeConverter; import org.springframework.beans.TypeConverter; import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.FactoryBean; +import org.springframework.core.convert.ConversionService; import org.springframework.integration.annotation.Gateway; +import org.springframework.integration.context.IntegrationContextUtils; import org.springframework.integration.core.Message; import org.springframework.integration.core.MessageChannel; import org.springframework.integration.endpoint.AbstractEndpoint; @@ -42,7 +45,11 @@ import org.springframework.util.StringUtils; /** * Generates a proxy for the provided service interface to enable interaction - * with messaging components without application code being aware of them. + * with messaging components without application code being aware of them allowing + * for POJO-style interaction. + * This component is also aware of the {@link ConversionService} set on the enclosing {@link BeanFactory} + * under the name {@link IntegrationContextUtils#INTEGRATION_CONVERSION_SERVICE_BEAN_NAME} to + * perform type conversions when necessary (thanks to Jon Schneider's contribution and suggestion in INT-1230). * * @author Mark Fisher * @author Oleg Zhurakousky @@ -238,7 +245,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory response = null; } } - return (response != null) ? this.typeConverter.convertIfNecessary(response, returnType) : null; + return (response != null) ? this.convert(response, returnType) : null; } private void rethrowExceptionInThrowsClauseIfPossible(Throwable originalException, Method method) throws Throwable { @@ -280,11 +287,11 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory replyChannel = this.resolveChannel(replyChannel, replyChannelName); String reqTimeout = gatewayDefinition.getRequestTimeout(); if (StringUtils.hasText(reqTimeout)){ - requestTimeout = typeConverter.convertIfNecessary(reqTimeout, Long.class); + requestTimeout = this.convert(reqTimeout, Long.class); } String repTimeout = gatewayDefinition.getReplyTimeout(); if (StringUtils.hasText(repTimeout)){ - replyTimeout = typeConverter.convertIfNecessary(repTimeout, Long.class); + replyTimeout = this.convert(repTimeout, Long.class); } } } @@ -345,4 +352,11 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Factory this.exceptionMapper = exceptionMapper; } + private T convert(Object source, Class expectedReturnType) { + if (this.getConversionService() != null) { + return this.getConversionService().convert(source, expectedReturnType); + } else { + return typeConverter.convertIfNecessary(source, expectedReturnType); + } + } } 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 71846feb7f..8865b54bd2 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 @@ -28,12 +28,17 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.junit.Test; - +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.support.ConversionServiceFactory; +import org.springframework.core.convert.support.GenericConversionService; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.channel.PollableChannel; import org.springframework.integration.channel.QueueChannel; +import org.springframework.integration.context.IntegrationContextUtils; import org.springframework.integration.core.Message; import org.springframework.integration.core.MessageChannel; import org.springframework.integration.endpoint.EventDrivenConsumer; @@ -45,6 +50,7 @@ import org.springframework.util.ReflectionUtils; /** * @author Mark Fisher + * @author Oleg Zhurakousky */ public class GatewayProxyFactoryBeanTests { @@ -61,6 +67,33 @@ public class GatewayProxyFactoryBeanTests { String result = service.requestReply("foo"); assertEquals("foobar", result); } + + @Test + public void testRequestReplyWithAnonymousChannelConvertedTypeViaConversionService() throws Exception { + QueueChannel requestChannel = new QueueChannel(); + startResponder(requestChannel); + GenericConversionService cs = ConversionServiceFactory.createDefaultConversionService(); + Converter stringToByteConverter = new Converter() { + public byte[] convert(String source) { + return source.getBytes(); + } + }; + stringToByteConverter = Mockito.spy(stringToByteConverter); + cs.addConverter(stringToByteConverter); + GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean(); + DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); + bf.registerSingleton(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME, cs); + + proxyFactory.setBeanFactory(bf); + proxyFactory.setDefaultRequestChannel(requestChannel); + proxyFactory.setServiceInterface(TestService.class); + proxyFactory.setBeanName("testGateway"); + proxyFactory.afterPropertiesSet(); + TestService service = (TestService) proxyFactory.getObject(); + byte[] result = service.requestReplyInBytes("foo"); + assertEquals(6, result.length); + Mockito.verify(stringToByteConverter, Mockito.times(1)).convert(Mockito.any(String.class)); + } @Test public void testOneWay() throws Exception { diff --git a/spring-integration-core/src/test/java/org/springframework/integration/gateway/TestService.java b/spring-integration-core/src/test/java/org/springframework/integration/gateway/TestService.java index 193c267992..9092b953c2 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/gateway/TestService.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/gateway/TestService.java @@ -20,10 +20,13 @@ import org.springframework.integration.core.Message; /** * @author Mark Fisher + * @author Oleg Zhurakousky */ public interface TestService { String requestReply(String input); + + byte[] requestReplyInBytes(String input); void oneWay(String input);