目录
- 1.编程式声明
- 补充:RabbitTemplate 和 AmqpAdmin 的区别
- 2.声明式声明
- 补充:new Queue() 和 QueueBuilder.durable(queueName).build() 的区别
背景:
在学习 RabbitMQ 的使用时, 经常会遇到不同的队列声明方式,有的是是使用
@Bean
注入,有的是通过channel.queueDeclare()
来声明队列,在此进行整理。
在 Spring Boot 集成 RabbitMQ 时,声明队列的方式主要分为两种:编程式声明
、声明式声明
。
1.编程式声明
- 直接在 Java 代码中通过 RabbitMQ 客户端 API(如:
com.rabbitmq.client.Channel
)声明队列。例如,使用rabbitTemplate.execute()
方法或amqpAdmin.declareQueue()
方法。
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private AmqpAdmin amqpAdmin;
// 使用RabbitTemplate
public void declareQueueWithRabbitTemplate(String queueName) throws IOException {
rabbitTemplate.execute(channel -> {
channel.queueDeclare(queueName, true, false, false, null);
return null;
});
}
// 使用AmqpAdmin
public void declareQueueWithAmqpAdmin(Queue queue) {
amqpAdmin.declareQueue(queue);
}
// 示例声明队列
public void declareMyQueue() {
Queue queue = new Queue("myQueue", true, false, false);
amqpAdmin.declareQueue(queue);
}
补充:RabbitTemplate 和 AmqpAdmin 的区别
1)RabbitTemplate:
RabbitTemplate
是 Spring AMQP 为开发者提供的一个模板类,用于简化发送和接收消息的操作。它封装了底层的 AMQP 客户端 API,提供了一系列方便的方法,如:convertAndSend()
:用于发送消息;receiveAndConvert()
:用于接收消息。
RabbitTemplate
可以直接发送和接收消息,同时也支持消息转换、回调函数等功能,用于处理消息的发送结果或处理接收到的消息内容。RabbitTemplate
主要用于日常消息的生产和消费操作,它具备丰富的消息转换和路由能力,能够大大简化 RabbitMQ 的交互代码。
2)AmqpAdmin:
AmqpAdmin
接口提供了管理和维护 AMQP 基础设施的能力,包括创建、删除交换机、队列和绑定关系等。- 实现
AmqpAmin
接口的典型类是RabbitAdmin
,它可以 在应用程序启动时自动检测并声明所需的交换机、队列和绑定,或者在运行时根据需要 动态管理这些资源。 AmqpAdmin
不涉及消息的发送和接收,而是 专注于 RabbitMQ 的配置和管理界面,确保消息的路由规则和存储结构已经就绪。
总结:
RabbitTemplate
更侧重于消息的发送和接收,而AmqpAdmin
更关注于 RabbitMQ 中间件本身的配置和管理。在实际项目中,通常会同时使用这两个组件来完成 RabbitMQ 的整体集成和消息流转。
2.声明式声明
- 通过 Spring AMQP 的 注解驱动 方式在启动时自动声明队列。这种方式更符合 Spring Boot 的 约定优于配置 的理念,更加简洁和自动化。例如:使用
@Bean
、@RabbitListener
注解。
@Configuration
public class RabbitConfig {
@Bean
public Queue myQueue() {
return new Queue("myQueue", true, false, false);
}
@Bean
public DirectExchange defaultExchange() {
return new DirectExchange("defaultExchange");
}
@Bean
public Binding binding(Queue myQueue, DirectExchange defaultExchange) {
return BindingBuilder.bind(myQueue).to(defaultExchange).with("routingKey");
}
@RabbitListener(queues = "myQueue")
public void processMessage(String message) {
// 处理消息逻辑
}
}
在上述代码中:
myQueue
Bean 会自动声明一个名为 myQueue 的队列;defaultExchange
Bean 会自动声明一个名为 defaultExchange 的直连交换机;binding
Bean 会将队列与交换机绑定起来;@RabbitListener
注解表明当有消息到达 “myQueue” 队列时,会调用processMessage
方法进行处理。
补充:new Queue() 和 QueueBuilder.durable(queueName).build() 的区别
在 Spring Boot 项目中使用 RabbitMQ 时,创建队列主要有两种方式:
- 直接实例化
Queue
对象; - 使用
QueueBuilder
构建器。
1)使用 new Queue(queueName)
创建:
new Queue("queueName");
源码如下:
/**
* The queue is durable, non-exclusive and non auto-delete.
* ------------------------------
* 队列是持久化的、非独占的、非自动删除的。
*
* @param name the name of the queue.
*/
public Queue(String name) {
this(name, true, false, false);
}
这种方式简单直接地创建了一个非持久化的、非独占的、自动删除的队列。这意味着:
- 持久化(durable): 如果 RabbitMQ 服务器重启,这个队列不会丢失。
- 非独占(non-exclusive): 多个消费者可以同时连接并消费该队列的消息。
- 非自动删除(non auto-delete): 当所有与该队列绑定的消费者都断开连接后,队列不会被自动删除。
2)使用 QueueBuilder.durable(queueName).build()
创建:
QueueBuilder.durable("queueName").build();
使用 QueueBuilder
可以更灵活的配置队列属性。上述代码创建的是一个持久化的队列,具有以下特点:
- 持久化(Durable): 即使 RabbitMQ 服务器重启,这个队列也会保留下来。
- 其他属性如:非独占、自动删除保持默认设置,即:不是独占的且不自动删除。
若要设置更多属性,可以继续调用 QueueBuilder
的方法,例如:
Queue queue = QueueBuilder.durable("queueName").build();
总结: 使用
new Queue(queueName)
的方式 只适用于需要快速创建一个非持久化的基本队列的情况。而通过QueueBuilder
则可以 根据需求详细配置队列的各种属性,包括但不限于:持久化、独占性和自动删除等。在生产环境中,为了保证消息可靠性,通常会选择创建持久化的队列,因此 推荐使用QueueBuilder.durable()
。
整理完毕,完结撒花~ 🌻