For the latest stable version, please use Spring AMQP 3.2.1! |
Message Conversion for Annotated Methods
There are two conversion steps in the pipeline before invoking the listener.
The first step uses a MessageConverter
to convert the incoming Spring AMQP Message
to a Spring-messaging Message
.
When the target method is invoked, the message payload is converted, if necessary, to the method parameter type.
The default MessageConverter
for the first step is a Spring AMQP SimpleMessageConverter
that handles conversion to
String
and java.io.Serializable
objects.
All others remain as a byte[]
.
In the following discussion, we call this the “message converter”.
The default converter for the second step is a GenericMessageConverter
, which delegates to a conversion service
(an instance of DefaultFormattingConversionService
).
In the following discussion, we call this the “method argument converter”.
To change the message converter, you can add it as a property to the container factory bean. The following example shows how to do so:
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
...
factory.setMessageConverter(new Jackson2JsonMessageConverter());
...
return factory;
}
This configures a Jackson2 converter that expects header information to be present to guide the conversion.
You can also use a ContentTypeDelegatingMessageConverter
, which can handle conversion of different content types.
Starting with version 2.3, you can override the factory converter by specifying a bean name in the messageConverter
property.
@Bean
public Jackson2JsonMessageConverter jsonConverter() {
return new Jackson2JsonMessageConverter();
}
@RabbitListener(..., messageConverter = "jsonConverter")
public void listen(String in) {
...
}
This avoids having to declare a different container factory just to change the converter.
In most cases, it is not necessary to customize the method argument converter unless, for example, you want to use
a custom ConversionService
.
In versions prior to 1.6, the type information to convert the JSON had to be provided in message headers, or a
custom ClassMapper
was required.
Starting with version 1.6, if there are no type information headers, the type can be inferred from the target
method arguments.
This type inference works only for @RabbitListener at the method level.
|
See Jackson2JsonMessageConverter
for more information.
If you wish to customize the method argument converter, you can do so as follows:
@Configuration
@EnableRabbit
public class AppConfig implements RabbitListenerConfigurer {
...
@Bean
public DefaultMessageHandlerMethodFactory myHandlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
factory.setMessageConverter(new GenericMessageConverter(myConversionService()));
return factory;
}
@Bean
public DefaultConversionService myConversionService() {
DefaultConversionService conv = new DefaultConversionService();
conv.addConverter(mySpecialConverter());
return conv;
}
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
registrar.setMessageHandlerMethodFactory(myHandlerMethodFactory());
}
...
}
For multi-method listeners (see Multi-method Listeners), the method selection is based on the payload of the message after the message conversion. The method argument converter is called only after the method has been selected. |