アノテーション付きメソッドのメッセージ変換

パイプラインには、リスナーを呼び出す前に 2 つの変換ステップがあります。最初のステップでは、MessageConverter を使用して、受信 Spring AMQP Message を Spring メッセージング Message に変換します。ターゲットメソッドが呼び出されると、必要に応じてメッセージペイロードがメソッドパラメーター型に変換されます。

最初のステップのデフォルトの MessageConverter は、String および java.io.Serializable オブジェクトへの変換を処理する Spring AMQP SimpleMessageConverter です。その他はすべて byte[] のままです。以下の説明では、これを「メッセージコンバーター」と呼びます。

2 番目のステップのデフォルトのコンバーターは、変換サービス ( DefaultFormattingConversionService のインスタンス) に委譲する GenericMessageConverter です。以下の説明では、これを「メソッド引数コンバーター」と呼びます。

メッセージコンバーターを変更するには、それをプロパティとしてコンテナーファクトリ 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());
    }

    ...

}
マルチメソッドリスナーの場合 ( マルチメソッドリスナーを参照)、メソッドの選択は、メッセージ変換後のメッセージのペイロードに基づいて行われます。メソッド引数コンバーターは、メソッドが選択された後にのみ呼び出されます。