对于最新的稳定版本,请使用 Spring AMQP 3.2.0! |
注释驱动的侦听器端点
异步接收消息的最简单方法是使用带注释的侦听器终端节点基础设施。
简而言之,它允许您将托管 bean 的方法公开为 Rabbit 侦听器终端节点。
以下示例演示如何使用@RabbitListener
注解:
@Component
public class MyService {
@RabbitListener(queues = "myQueue")
public void processOrder(String data) {
...
}
}
前面示例的思路是,只要在名为myQueue
这processOrder
method (在本例中,使用消息的有效负载)。
带注释的终端节点基础设施在后台为每个带注释的方法创建一个消息侦听器容器,方法是使用RabbitListenerContainerFactory
.
在前面的示例中,myQueue
必须已经存在并绑定到某个 exchange。
队列可以自动声明和绑定,只要RabbitAdmin
存在于应用程序上下文中。
属性占位符 (${some.property} ) 或 SPEL 表达式 (#{someExpression} ) 可以为注释属性 (queues 等)。
有关为什么可以使用 SPEL 而不是属性占位符的示例,请参见侦听多个队列。
下面的清单显示了如何声明 Rabbit 侦听器的三个示例: |
@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
自动声明 (durable) 与 Exchange 一起(如果需要),
并使用路由密钥绑定到 Exchange。
在第二个示例中,声明并绑定了一个匿名(独占、自动删除)队列;队列名称由框架使用Base64UrlNamingStrategy
.
您不能使用此技术声明代理命名的队列;它们需要声明为 bean 定义;请参阅 容器和 Broker-Named 队列。
倍数QueueBinding
条目,让侦听器侦听多个队列。
在第三个示例中,名称为 retrieved from 属性的队列my.queue
如有必要,使用队列名称作为路由键来声明默认绑定到默认 Exchange。
从 2.0 版本开始,@Exchange
annotation 支持任何 Exchange 类型,包括 CUSTOM。
有关更多信息,请参阅 AMQP 概念。
您可以使用 normal@Bean
definitions 来定义。
通知ignoreDeclarationExceptions
在第一个例子中的 EXCHANGE 上。
例如,这允许绑定到可能具有不同设置的现有 Exchange(例如internal
).
默认情况下,现有 Exchange 的属性必须匹配。
从版本 2.0 开始,您现在可以将队列绑定到具有多个路由键的 Exchange,如下例所示:
...
key = { "red", "yellow" }
...
您还可以在@QueueBinding
队列、交易所、
和 bindings,如下例所示:
@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
header 设置为somevalue
和
这thing2
header 必须与任何值一起存在。
这x-match
argument 表示必须同时满足这两个条件。
参数名称、值和类型可以是属性占位符 (${…}
) 或 SPEL 表达式 (#{…}
).
这name
必须解析为String
.
的表达式type
必须解析为Class
或类的完全限定名称。
这value
必须解析为可由DefaultConversionService
添加到类型(例如x-message-ttl
在前面的示例中)。
如果名称解析为null
或空的String
那@Argument
被忽略。