请使用 Spring AMQP 4.0.2(最新稳定版本)!spring-doc.cadn.net.cn

带注解方法的消息转换

管道中在调用监听器之前有两个转换步骤。第一个步骤使用 MessageConverter 将传入的 Spring AMQP Message 转换为 Spring-messaging Message。当目标方法被调用时,如果需要,会将消息负载转换为方法参数类型。spring-doc.cadn.net.cn

第一步的默认值 MessageConverter 是一个 Spring AMQP SimpleMessageConverter,它负责将消息转换为 Stringjava.io.Serializable 对象。其余所有情况均保持为 byte[]。在下文讨论中,我们称其为“消息转换器”。spring-doc.cadn.net.cn

第二步的默认转换器是 GenericMessageConverter,它委托给一个转换服务(DefaultFormattingConversionService 的实例)。在下文讨论中,我们称其为“方法参数转换器”。spring-doc.cadn.net.cn

要更改消息转换器,可以将其作为属性添加到容器工厂 Bean 中。以下示例展示了如何实现这一点:spring-doc.cadn.net.cn

@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    ...
    factory.setMessageConverter(new Jackson2JsonMessageConverter());
    ...
    return factory;
}

此配置了一个 Jackson2 转换器,该转换器期望存在头部信息以指导转换过程。spring-doc.cadn.net.cn

您还可以使用 ContentTypeDelegatingMessageConverter,它能够处理不同内容类型的转换。spring-doc.cadn.net.cn

从版本 2.3 开始,您可以通过在 messageConverter 属性中指定一个 bean 名称来覆盖工厂转换器。spring-doc.cadn.net.cn

@Bean
public Jackson2JsonMessageConverter jsonConverter() {
    return new Jackson2JsonMessageConverter();
}

@RabbitListener(..., messageConverter = "jsonConverter")
public void listen(String in) {
    ...
}

这避免了为更改转换器而必须声明不同的容器工厂。spring-doc.cadn.net.cn

在大多数情况下,除非例如您希望使用自定义 ConversionService,否则无需自定义方法参数转换器。spring-doc.cadn.net.cn

在 1.6 版本之前的版本中,将 JSON 转换为类型的信息必须在消息头中提供,或者需要自定义 ClassMapper
从 1.6 版本开始,如果没有类型信息头,则可以从目标方法参数中推断出类型。spring-doc.cadn.net.cn

这种类型推断仅适用于方法级别的 @RabbitListener

参见 Jackson2JsonMessageConverter 以获取更多信息。spring-doc.cadn.net.cn

如果您希望自定义方法参数转换器,可以按如下方式操作:spring-doc.cadn.net.cn

@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());
    }

    ...

}
对于多方法监听器(参见 多方法监听器),方法选择基于消息在消息转换之后的负载。方法参数转换器仅在方法被选定后才会调用。