GH-1269: @RabbitListener: Allow other Annotations

Resolves https://github.com/spring-projects/spring-amqp/issues/1269

Previously, a parameter annotated with a "foreign" annoation (e.g. `@Validated`)
would not be considered as an eligible payload conversion target; it must also
have been annotated with `@Payload`.

- remove the check for zero annotations
- add a check that the method is not annotated with both `@Payload` and `@Header`
  - ignore if it does, with a warn log, to be consistent with previous behavior.
  - in a future release we might consider this to be fatal.

**cherry-pick to 2.2.x**
This commit is contained in:
Gary Russell
2020-11-25 13:08:59 -05:00
committed by Artem Bilan
parent fed2f3170a
commit 39c9c44caf
2 changed files with 31 additions and 6 deletions

View File

@@ -34,6 +34,7 @@ import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.remoting.support.RemoteInvocationResult;
@@ -333,12 +334,21 @@ public class MessagingMessageListenerAdapter extends AbstractAdaptableMessageLis
for (int i = 0; i < this.method.getParameterCount(); i++) {
MethodParameter methodParameter = new MethodParameter(this.method, i);
/*
* We're looking for a single non-annotated parameter, or one annotated with @Payload.
* We're looking for a single parameter, or one annotated with @Payload.
* We ignore parameters with type Message because they are not involved with conversion.
*/
boolean isHeader = methodParameter.hasParameterAnnotation(Header.class);
boolean isPayload = methodParameter.hasParameterAnnotation(Payload.class);
if (isHeader && isPayload) {
if (MessagingMessageListenerAdapter.this.logger.isWarnEnabled()) {
MessagingMessageListenerAdapter.this.logger.warn(this.method.getName()
+ ": Cannot annotate a parameter with both @Header and @Payload; "
+ "ignored for payload conversion");
}
}
if (isEligibleParameter(methodParameter)
&& (methodParameter.getParameterAnnotations().length == 0
|| methodParameter.hasParameterAnnotation(Payload.class))) {
&& (!isHeader || isPayload) && !(isHeader && isPayload)) {
if (genericParameterType == null) {
genericParameterType = extractGenericParameterTypFromMethodParameter(methodParameter);
}

View File

@@ -131,6 +131,7 @@ import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ErrorHandler;
import org.springframework.validation.annotation.Validated;
import com.rabbitmq.client.Channel;
import com.rabbitmq.http.client.Client;
@@ -1148,8 +1149,9 @@ public class EnableRabbitIntegrationTests {
}
@RabbitListener(id = "different", queues = "differentTypes", containerFactory = "jsonListenerContainerFactory")
public void handleDifferent(Foo2 foo) {
@RabbitListener(id = "different", queues = "differentTypes",
containerFactory = "jsonListenerContainerFactoryNoClassMapper")
public void handleDifferent(@Validated Foo2 foo) {
foos.add(foo);
latch.countDown();
}
@@ -1592,6 +1594,19 @@ public class EnableRabbitIntegrationTests {
return factory;
}
@Bean
public SimpleRabbitListenerContainerFactory jsonListenerContainerFactoryNoClassMapper() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(rabbitConnectionFactory());
factory.setErrorHandler(errorHandler());
factory.setConsumerTagStrategy(consumerTagStrategy());
Jackson2JsonMessageConverter messageConverter = new Jackson2JsonMessageConverter();
factory.setMessageConverter(messageConverter);
factory.setReceiveTimeout(10L);
factory.setConcurrentConsumers(2);
return factory;
}
@Bean
public MeterRegistry meterRegistry() {
return new SimpleMeterRegistry();
@@ -2189,7 +2204,7 @@ public class EnableRabbitIntegrationTests {
}
@RabbitListener(queues = "test.converted.args2")
public String foo2a(@Payload Foo2 foo2, @Header("amqp_consumerQueue") String queue) {
public String foo2a(Foo2 foo2, @Header("amqp_consumerQueue") String queue) {
return foo2 + queue;
}