diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderFactoryConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderFactoryConfiguration.java index 080f20daf..3e657f18c 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderFactoryConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/config/BinderFactoryConfiguration.java @@ -17,6 +17,7 @@ package org.springframework.cloud.stream.config; import java.io.IOException; +import java.lang.reflect.Field; import java.net.URL; import java.util.ArrayList; import java.util.Collection; @@ -62,6 +63,7 @@ import org.springframework.messaging.handler.annotation.support.HeadersMethodArg import org.springframework.messaging.handler.annotation.support.MessageHandlerMethodFactory; import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver; import org.springframework.util.ClassUtils; +import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; import org.springframework.validation.Validator; @@ -189,6 +191,13 @@ public class BinderFactoryConfiguration { resolvers.add(new HeadersMethodArgumentResolver()); resolvers.addAll(ahmar.getResolvers()); + // modify HandlerMethodArgumentResolversHolder + Field field = ReflectionUtils.findField(HandlerMethodArgumentResolversHolder.class, "resolvers"); + field.setAccessible(true); + ((List) ReflectionUtils.getField(field, ahmar)).clear(); + resolvers.forEach(ahmar::addResolver); + // -- + messageHandlerMethodFactory.setArgumentResolvers(resolvers); messageHandlerMethodFactory.setValidator(validator); return messageHandlerMethodFactory; diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/tck/ContentTypeTckTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/tck/ContentTypeTckTests.java index c3e0e264c..6a0e004e9 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/tck/ContentTypeTckTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/binder/tck/ContentTypeTckTests.java @@ -1051,4 +1051,28 @@ public class ContentTypeTckTests { return value; } } + + @Test + public void testWithTypelessInputParameterAndServiceActivator() { + ApplicationContext context = new SpringApplicationBuilder(TypelessPayloadConfigurationSA.class) + .web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false"); + InputDestination source = context.getBean(InputDestination.class); + OutputDestination target = context.getBean(OutputDestination.class); + String jsonPayload = "[\"foo\",\"bar\"]"; + source.send(MessageBuilder.withPayload(jsonPayload.getBytes()).build()); + Message outputMessage = target.receive(); + assertEquals(jsonPayload, new String(outputMessage.getPayload(), StandardCharsets.UTF_8)); + } + + @EnableBinding(Processor.class) + @Import(TestChannelBinderConfiguration.class) + @EnableAutoConfiguration + public static class TypelessPayloadConfigurationSA { + @ServiceActivator(inputChannel=Processor.INPUT, outputChannel=Processor.OUTPUT) + public Object echo(Object value) throws Exception { + System.out.println(value); + return value; + } + } }