注解方法的消息转换
在调用监听器之前,管道中有两个转换步骤。第一步使用 MessageConverter 将传入的 Spring AMQP Message 转换为 Spring-messaging Message。当调用目标方法时,消息载荷会在必要时被转换为方法参数类型。
第一步的默认 MessageConverter 是 Spring AMQP 的 SimpleMessageConverter,它处理到 String 和 java.io.Serializable 对象的转换。其他所有类型都保持为 byte[]。在下面的讨论中,我们称之为"消息转换器"。
第二步的默认转换器是 GenericMessageConverter,它委托给一个转换服务(DefaultFormattingConversionService 的实例)。在下面的讨论中,我们称之为"方法参数转换器"。
要更改消息转换器,你可以将其作为属性添加到容器工厂 bean。下面的示例展示了如何这样做:
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
...
factory.setMessageConverter(new Jackson2JsonMessageConverter());
...
return factory;
}
这会配置一个 Jackson2 转换器,它期望存在消息头信息以指导转换。
你还可以使用 ContentTypeDelegatingMessageConverter,它可以处理不同内容类型的转换。
从 2.3 版开始,你可以通过在 messageConverter 属性中指定 bean 名来覆盖工厂转换器。
@Bean
public Jackson2JsonMessageConverter jsonConverter() {
return new Jackson2JsonMessageConverter();
}
@RabbitListener(..., messageConverter = "jsonConverter")
public void listen(String in) {
...
}
这样就避免了仅仅为了更改转换器而声明一个不同的容器工厂。
在大多数情况下,没有必要定制方法参数转换器,除非例如你想使用自定义的 ConversionService。
在 1.6 之前的版本中,转换 JSON 的类型信息必须在消息头中提供,或者需要一个自定义的 ClassMapper。从 1.6 版开始,如果没有类型信息消息头,则可以从目标方法参数推断类型。
这种类型推断仅适用于方法级别的 @RabbitListener。
更多信息请参阅 Jackson2JsonMessageConverter。
如果你希望定制方法参数转换器,可以按如下方式进行:
@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());
}
...
}
对于多方法监听器(请参阅多方法监听器),方法选择是基于消息转换之后的消息载荷。方法参数转换器仅在方法选定之后才被调用。