此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring AMQP 3.2.6! |
注释驱动的侦听器端点
异步接收消息的最简单方法是使用带注释的侦听器端点基础架构。简而言之,它允许您将托管 Bean 的方法公开为 Rabbit 侦听器端点。以下示例显示如何使用@RabbitListener
注解:
@Component
public class MyService {
@RabbitListener(queues = "myQueue")
public void processOrder(String data) {
...
}
}
前面示例的思想是,每当名为myQueue
这processOrder
方法被相应地调用(在本例中,使用消息的有效负载)。
带注释的端点基础结构在后台为每个带注释的方法创建一个消息侦听器容器,方法是使用RabbitListenerContainerFactory
.
在前面的示例中,myQueue
必须已经存在并绑定到某个交换。队列可以自动声明和绑定,只要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
与交换一起自动声明(持久),如果需要,并使用路由密钥绑定到交换。在第二个示例中,声明并绑定了一个匿名(独占、自动删除)队列;队列名称由框架使用Base64UrlNamingStrategy
. 您不能使用此技术声明代理命名的队列;它们需要声明为 Bean 定义;请参阅容器和代理命名队列。 倍数QueueBinding
可以提供条目,让侦听器监听多个队列。在第三个示例中,名称为 Retrieved from 属性的队列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
header 设置为somevalue
和 这thing2
header 必须与任何值一起存在。 这x-match
参数表示必须满足这两个条件。
参数名称、值和类型可以是属性占位符 (${…}
) 或 SpEL 表达式 (#{…}
). 这name
必须解析为String
. 的表达式type
必须解析为Class
或类的完全限定名称。 这value
必须解析为可以通过DefaultConversionService
设置为类型(例如x-message-ttl
在前面的示例中)。
如果名称解析为null
或空的String
那@Argument
被忽略。