用於註解方法的訊息轉換

在調用監聽器之前,管線中有兩個轉換步驟。 第一個步驟使用 MessageConverter 將傳入的 Spring AMQP Message 轉換為 Spring-messaging Message。 當調用目標方法時,訊息酬載會轉換為方法參數類型(如有必要)。

第一個步驟的預設 MessageConverter 是 Spring AMQP SimpleMessageConverter,它處理轉換為 Stringjava.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());
    }

    ...

}
對於多方法監聽器(請參閱 多方法監聽器),方法選擇是基於訊息轉換後的訊息酬載。 方法引數轉換器僅在選擇方法後調用。