此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.4.3! |
AMQP
高级消息队列协议 (AMQP) 是一种平台中立的有线级协议,适用于面向消息的中间件。
Spring AMQP 项目将核心 Spring 概念应用于基于 AMQP 的消息传递解决方案的开发。
Spring Boot 为通过 RabbitMQ 使用 AMQP 提供了多种便利,包括spring-boot-starter-amqp
起动机。
RabbitMQ 支持
RabbitMQ 是基于 AMQP 协议的轻量级、可靠、可扩展且可移植的消息代理。 Spring 使用 RabbitMQ 通过 AMQP 协议进行通信。
RabbitMQ 配置由spring.rabbitmq.*
.
例如,您可以在application.properties
:
-
Properties
-
YAML
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=secret
spring:
rabbitmq:
host: "localhost"
port: 5672
username: "admin"
password: "secret"
或者,您可以使用addresses
属性:
-
Properties
-
YAML
spring.rabbitmq.addresses=amqp://admin:secret@localhost
spring:
rabbitmq:
addresses: "amqp://admin:secret@localhost"
以这种方式指定地址时,host 和port properties 将被忽略。
如果地址使用amqps 协议,则会自动启用 SSL 支持。 |
看RabbitProperties
,了解更多受支持的基于属性的配置选项。
配置 RabbitMQ 的较低级别详细信息ConnectionFactory
,定义一个ConnectionFactoryCustomizer
豆。
如果ConnectionNameStrategy
bean 存在于上下文中,它将自动用于命名由自动配置的CachingConnectionFactory
.
有关更多详细信息,请参阅了解 RabbitMQ 使用的协议 AMQP。 |
发送消息
Spring的AmqpTemplate
和AmqpAdmin
是自动配置的,你可以将它们直接自动连接到你自己的 bean 中,如以下示例所示:
-
Java
-
Kotlin
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final AmqpAdmin amqpAdmin;
private final AmqpTemplate amqpTemplate;
public MyBean(AmqpAdmin amqpAdmin, AmqpTemplate amqpTemplate) {
this.amqpAdmin = amqpAdmin;
this.amqpTemplate = amqpTemplate;
}
// ...
public void someMethod() {
this.amqpAdmin.getQueueInfo("someQueue");
}
public void someOtherMethod() {
this.amqpTemplate.convertAndSend("hello");
}
}
import org.springframework.amqp.core.AmqpAdmin
import org.springframework.amqp.core.AmqpTemplate
import org.springframework.stereotype.Component
@Component
class MyBean(private val amqpAdmin: AmqpAdmin, private val amqpTemplate: AmqpTemplate) {
// ...
fun someMethod() {
amqpAdmin.getQueueInfo("someQueue")
}
fun someOtherMethod() {
amqpTemplate.convertAndSend("hello")
}
}
RabbitMessagingTemplate
can be injected in a similar manner.
If a MessageConverter
bean is defined, it is associated automatically to the auto-configured AmqpTemplate
.
If necessary, any Queue
that is defined as a bean is automatically used to declare a corresponding queue on the RabbitMQ instance.
To retry operations, you can enable retries on the AmqpTemplate
(for example, in the event that the broker connection is lost):
-
Properties
-
YAML
spring.rabbitmq.template.retry.enabled=true
spring.rabbitmq.template.retry.initial-interval=2s
spring:
rabbitmq:
template:
retry:
enabled: true
initial-interval: "2s"
Retries are disabled by default.
You can also customize the RetryTemplate
programmatically by declaring a RabbitRetryTemplateCustomizer
bean.
If you need to create more RabbitTemplate
instances or if you want to override the default, Spring Boot provides a RabbitTemplateConfigurer
bean that you can use to initialize a RabbitTemplate
with the same settings as the factories used by the auto-configuration.
Sending a Message To A Stream
To send a message to a particular stream, specify the name of the stream, as shown in the following example:
-
Properties
-
YAML
spring.rabbitmq.stream.name=my-stream
spring:
rabbitmq:
stream:
name: "my-stream"
If a MessageConverter
, StreamMessageConverter
, or ProducerCustomizer
bean is defined, it is associated automatically to the auto-configured RabbitStreamTemplate
.
If you need to create more RabbitStreamTemplate
instances or if you want to override the default, Spring Boot provides a RabbitStreamTemplateConfigurer
bean that you can use to initialize a RabbitStreamTemplate
with the same settings as the factories used by the auto-configuration.
Receiving a Message
When the Rabbit infrastructure is present, any bean can be annotated with @RabbitListener
to create a listener endpoint.
If no RabbitListenerContainerFactory
has been defined, a default SimpleRabbitListenerContainerFactory
is automatically configured and you can switch to a direct container using the spring.rabbitmq.listener.type
property.
If a MessageConverter
or a MessageRecoverer
bean is defined, it is automatically associated with the default factory.
The following sample component creates a listener endpoint on the someQueue
queue:
-
Java
-
Kotlin
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
@RabbitListener(queues = "someQueue")
public void processMessage(String content) {
// ...
}
}
import org.springframework.amqp.rabbit.annotation.RabbitListener
import org.springframework.stereotype.Component
@Component
class MyBean {
@RabbitListener(queues = ["someQueue"])
fun processMessage(content: String?) {
// ...
}
}
See @EnableRabbit
for more details.
If you need to create more RabbitListenerContainerFactory
instances or if you want to override the default, Spring Boot provides a SimpleRabbitListenerContainerFactoryConfigurer
and a DirectRabbitListenerContainerFactoryConfigurer
that you can use to initialize a SimpleRabbitListenerContainerFactory
and a DirectRabbitListenerContainerFactory
with the same settings as the factories used by the auto-configuration.
It does not matter which container type you chose.
Those two beans are exposed by the auto-configuration.
For instance, the following configuration class exposes another factory that uses a specific MessageConverter
:
-
Java
-
Kotlin
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyRabbitConfiguration {
@Bean
public SimpleRabbitListenerContainerFactory myFactory(SimpleRabbitListenerContainerFactoryConfigurer configurer) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
ConnectionFactory connectionFactory = getCustomConnectionFactory();
configurer.configure(factory, connectionFactory);
factory.setMessageConverter(new MyMessageConverter());
return factory;
}
private ConnectionFactory getCustomConnectionFactory() {
return ...
}
}
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory
import org.springframework.amqp.rabbit.connection.ConnectionFactory
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyRabbitConfiguration {
@Bean
fun myFactory(configurer: SimpleRabbitListenerContainerFactoryConfigurer): SimpleRabbitListenerContainerFactory {
val factory = SimpleRabbitListenerContainerFactory()
val connectionFactory = getCustomConnectionFactory()
configurer.configure(factory, connectionFactory)
factory.setMessageConverter(MyMessageConverter())
return factory
}
fun getCustomConnectionFactory() : ConnectionFactory? {
return ...
}
}
Then you can use the factory in any @RabbitListener
-annotated method, as follows:
-
Java
-
Kotlin
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
@RabbitListener(queues = "someQueue", containerFactory = "myFactory")
public void processMessage(String content) {
// ...
}
}
import org.springframework.amqp.rabbit.annotation.RabbitListener
import org.springframework.stereotype.Component
@Component
class MyBean {
@RabbitListener(queues = ["someQueue"], containerFactory = "myFactory")
fun processMessage(content: String?) {
// ...
}
}
You can enable retries to handle situations where your listener throws an exception.
By default, RejectAndDontRequeueRecoverer
is used, but you can define a MessageRecoverer
of your own.
When retries are exhausted, the message is rejected and either dropped or routed to a dead-letter exchange if the broker is configured to do so.
By default, retries are disabled.
You can also customize the RetryTemplate
programmatically by declaring a RabbitRetryTemplateCustomizer
bean.
By default, if retries are disabled and the listener throws an exception, the delivery is retried indefinitely.
You can modify this behavior in two ways: Set the defaultRequeueRejected
property to false
so that zero re-deliveries are attempted or throw an AmqpRejectAndDontRequeueException
to signal the message should be rejected.
The latter is the mechanism used when retries are enabled and the maximum number of delivery attempts is reached.