アノテーション駆動型のリスナーエンドポイント

メッセージを非同期で受信する最も簡単な方法は、アノテーション付きのリスナーエンドポイントインフラストラクチャを使用することです。簡単に言うと、マネージ Bean のメソッドを Rabbit リスナーエンドポイントとして公開できます。次の例は、@RabbitListener アノテーションの使用方法を示しています。

@Component
public class MyService {

    @RabbitListener(queues = "myQueue")
    public void processOrder(String data) {
        ...
    }

}

前の例の考え方は、メッセージが myQueue という名前のキューで利用可能になるたびに、それに応じて processOrder メソッドが呼び出されるということです (この場合は、メッセージのペイロードを使用して)。

アノテーション付きエンドポイントインフラストラクチャは、RabbitListenerContainerFactory を使用して、アノテーション付きメソッドごとにバックグラウンドでメッセージリスナーコンテナーを作成します。

前の例では、myQueue がすでに存在し、何らかの交換にバインドされている必要があります。アプリケーションコンテキストに RabbitAdmin が存在する限り、キューは自動的に宣言およびバインドできます。

アノテーションプロパティ (queues など) には、プロパティプレースホルダー (${some.property}) または SpEL 式 (#{someExpression}) を指定できます。プロパティプレースホルダーの代わりに SpEL を使用する理由の例については、複数のキューをリッスンするを参照してください。次のリストは、Rabbit リスナーを宣言する方法の 3 つの例を示しています。
@Component
public class MyService {

  @RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "myQueue", durable = "true"),
        exchange = @Exchange(value = "auto.exch", ignoreDeclarationExceptions = "true"),
        key = "orderRoutingKey")
  )
  public void processOrder(Order order) {
    ...
  }

  @RabbitListener(bindings = @QueueBinding(
        value = @Queue,
        exchange = @Exchange(value = "auto.exch"),
        key = "invoiceRoutingKey")
  )
  public void processInvoice(Invoice invoice) {
    ...
  }

  @RabbitListener(queuesToDeclare = @Queue(name = "${my.queue}", durable = "true"))
  public String handleWithSimpleDeclare(String data) {
      ...
  }

}

最初の例では、キュー myQueue は、必要に応じて交換とともに自動的に (永続的に) 宣言され、ルーティングキーを使用して交換にバインドされます。2 番目の例では、匿名 (排他的、自動削除) キューが宣言され、バインドされています。キュー名は Base64UrlNamingStrategy を使用してフレームワークによって作成されます。この手法を使用してブローカー名のキューを宣言することはできません。それらは Bean 定義として宣言する必要があります。コンテナーとブローカー名のキューを参照してください。複数の QueueBinding エントリを指定して、リスナーが複数のキューをリッスンできるようにすることができます。3 番目の例では、プロパティ my.queue から取得された名前を持つキューが宣言され、必要に応じて、キュー名をルーティングキーとして使用して、既定のエクスチェンジにバインドされます。

バージョン 2.0 以降、@Exchange アノテーションは、カスタムを含むすべての交換型をサポートしています。詳細については、AMQP の概念 (英語) を参照してください。

より高度な構成が必要な場合は、通常の @Bean 定義を使用できます。

最初の例の交換の ignoreDeclarationExceptions に注目してください。これにより、たとえば、設定が異なる既存の交換 ( internal など) にバインドできます。デフォルトでは、既存の交換のプロパティが一致する必要があります。

バージョン 2.0 以降では、次の例に示すように、複数のルーティングキーを使用してキューを交換にバインドできるようになりました。

...
    key = { "red", "yellow" }
...

次の例に示すように、キュー、交換、バインディングの @QueueBinding アノテーション内に引数を指定することもできます。

@RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "auto.headers", autoDelete = "true",
                        arguments = @Argument(name = "x-message-ttl", value = "10000",
                                                type = "java.lang.Integer")),
        exchange = @Exchange(value = "auto.headers", type = ExchangeTypes.HEADERS, autoDelete = "true"),
        arguments = {
                @Argument(name = "x-match", value = "all"),
                @Argument(name = "thing1", value = "somevalue"),
                @Argument(name = "thing2")
        })
)
public String handleWithHeadersExchange(String foo) {
    ...
}

キューの x-message-ttl 引数が 10 秒に設定されていることに注意してください。引数の型は String ではないため、その型 (この場合は Integer) を指定する必要があります。このようなすべての宣言と同様に、キューがすでに存在する場合、引数はキューの引数と一致する必要があります。ヘッダー交換では、thing1 ヘッダーが somevalue に設定されたメッセージと一致するようにバインド引数を設定し、thing2 ヘッダーには任意の値が存在する必要があります。x-match 引数は、両方の条件を満たす必要があることを意味します。

引数の名前、値、型は、プロパティプレースホルダー (${…​}) または SpEL 式 (#{…​}) にすることができます。name は String に解決される必要があります。type の式は、Class またはクラスの完全修飾名に解決される必要があります。value は、DefaultConversionService によって型に変換できるもの (前の例の x-message-ttl など) に解決される必要があります。

名前が null または空の String に解決される場合、その @Argument は無視されます。