对于RabbitMQ的开发,Spring方法提供了更为方便的操作.
Spring官网介绍: Spring AMQP
RabbitMQ官网介绍: RabbitMQ tutorial - "Hello World!" | RabbitMQ
引入依赖
为了方便测试也引入SpringWeb依赖.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
添加配置
#配置RabbitMQ的基本信息
spring:
rabbitmq:
host: # IP地址
port: 5672 #端口号 默认5672
username: #用户名
password: #密码
virtual-host: #虚拟主机
# 以上写法也可以整合成下面这种写法
# addresses: amqp://用户名:密码@IP地址:端口号/虚拟主机
工作模式代码
相关常量
public class Constants {
//工作队列模式
public static final String WORK_QUEUE = "work.queue";
}
相关配置
import com.example.rabbitmqspringboot.constant.Constants;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
// 工作队列模式
// 工作队列交给Spring管理
@Bean("workQueue")
public Queue workQueue(){
return QueueBuilder.durable(Constants.WORK_QUEUE).build();
}
}
生产者
import com.example.rabbitmqspringboot.constant.Constants;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/producer")
@RestController
public class ProducerController {
// 引入RabbitTemplate 这是Spring Boot提供的RabbitMQ客户端相关操作
@Autowired
private RabbitTemplate rabbitTemplate;
// 工作模式的生产者代码
@RequestMapping("/work")
public String work(){
for (int i = 0; i < 10; i++) {
//使用内置交换机, RoutingKey 和队列名称一致
rabbitTemplate.convertAndSend("", Constants.WORK_QUEUE, "hello spring amqp: work..."+i);
}
return "发送成功";
}
}
消费者
import com.example.rabbitmqspringboot.constant.Constants;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class WorkListener {
/**
* RabbitListener是 Spring 框架中用于监听 RabbitMQ 队列的注解。
* 通过使用这个注解,可以定义一个方法,以便从 RabbitMQ 队列中接收消息。
* 该注解支持多种参数类型,这些参数类型代表了从 RabbitMQ 接收到的消息和相关信息。
*
* 以下是一些常用的参数类型:
* String:返回消息的内容。
* Message (org.springframework.amqp.core.Message):Spring AMQP 的 Message 类,返回原始的消息体以及消息的属性,如消息 ID、内容、队列信息等。
* Channel (com.rabbitmq.client.Channel):RabbitMQ 的通道对象,可以用于进行更高级的操作,如手动确认消息。
*/
// 监听队列
// 通常来说@RabbitListener注解是放到类上的,表示这个类作为一个消费者
// 这里为了方便,将监听队列放到方法上,表示这个方法是一个消费者。所以这里有两个消费者
@RabbitListener(queues = Constants.WORK_QUEUE)
public void queueListener1(Message message, Channel channel){
System.out.println("listener 1 ["+Constants.WORK_QUEUE+"] 接收到消息:" +message + ",channel:"+channel);
}
@RabbitListener(queues = Constants.WORK_QUEUE)
public void queueListener2(String message){
System.out.println("listener 2 ["+Constants.WORK_QUEUE+"] 接收到消息:" +message);
}
}
结果
其他工作模式整合
以下代码整合发布/订阅模式, 路由模式和通配符模式
相关常量
public class Constants {
//工作队列模式
public static final String WORK_QUEUE = "work.queue";
//发布订阅模式
public static final String FANOUT_QUEUE1 = "fanout.queue1";
public static final String FANOUT_QUEUE2 = "fanout.queue2";
public static final String FANOUT_EXCHANGE = "fanout.exchange";
//路由模式
public static final String DIRECT_QUEUE1 = "direct.queue1";
public static final String DIRECT_QUEUE2 = "direct.queue2";
public static final String DIRECT_EXCHANGE = "direct.exchange";
//通配符模式
public static final String TOPIC_QUEUE1 = "topic.queue1";
public static final String TOPIC_QUEUE2 = "topic.queue2";
public static final String TOPIC_EXCHANGE = "topic.exchange";
}
相关配置
import com.example.rabbitmqspringboot.constant.Constants;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
// 工作队列模式
// 工作队列交给Spring管理
@Bean("workQueue")
public Queue workQueue(){
return QueueBuilder.durable(Constants.WORK_QUEUE).build();
}
// 发布订阅模式
// 创建队列 创建交换机 绑定队列和交换机
@Bean("fanoutQueue1")
public Queue fanoutQueue1(){
return QueueBuilder.durable(Constants.FANOUT_QUEUE1).build();
}
@Bean("fanoutQueue2")
public Queue fanoutQueue2(){
return QueueBuilder.durable(Constants.FANOUT_QUEUE2).build();
}
@Bean("fanoutExchange")
public FanoutExchange fanoutExchange(){
return ExchangeBuilder.fanoutExchange(Constants.FANOUT_EXCHANGE).durable(true).build();
}
@Bean("fanoutQueueBinding1")
public Binding fanoutQueueBinding1(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange, @Qualifier("fanoutQueue1") Queue queue){
return BindingBuilder.bind(queue).to(fanoutExchange);
}
@Bean("fanoutQueueBinding2")
public Binding fanoutQueueBinding2(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange, @Qualifier("fanoutQueue2") Queue queue){
return BindingBuilder.bind(queue).to(fanoutExchange);
}
//路由模式
// 队列1 和 交换机 绑定,路由键为orange
// 队列2 和 交换机 绑定,路由键为black
// 队列2 和 交换机 绑定,路由键为orange
@Bean("directQueue1")
public Queue directQueue1(){
return QueueBuilder.durable(Constants.DIRECT_QUEUE1).build();
}
@Bean("directQueue2")
public Queue directQueue2(){
return QueueBuilder.durable(Constants.DIRECT_QUEUE2).build();
}
@Bean("directExchange")
public DirectExchange directExchange(){
return ExchangeBuilder.directExchange(Constants.DIRECT_EXCHANGE).durable(true).build();
}
@Bean("directQueueBinding1")
public Binding directQueueBinding1(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue1") Queue queue){
return BindingBuilder.bind(queue).to(directExchange).with("orange");
}
@Bean("directQueueBinding2")
public Binding directQueueBinding2(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue2") Queue queue){
return BindingBuilder.bind(queue).to(directExchange).with("black");
}
@Bean("directQueueBinding3")
public Binding directQueueBinding3(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue2") Queue queue){
return BindingBuilder.bind(queue).to(directExchange).with("orange");
}
//通配符模式
// 队列1 和 交换机 绑定,路由键为 *.orange.*
// 队列2 和 交换机 绑定,路由键为 *.*.rabbit
// 队列2 和 交换机 绑定,路由键为 lazy.#
@Bean("topicQueue1")
public Queue topicQueue1(){
return QueueBuilder.durable(Constants.TOPIC_QUEUE1).build();
}
@Bean("topicQueue2")
public Queue topicQueue2(){
return QueueBuilder.durable(Constants.TOPIC_QUEUE2).build();
}
@Bean("topicExchange")
public TopicExchange topicExchange(){
return ExchangeBuilder.topicExchange(Constants.TOPIC_EXCHANGE).durable(true).build();
}
@Bean("topicQueueBinding1")
public Binding topicQueueBinding1(@Qualifier("topicExchange") TopicExchange topicExchange, @Qualifier("topicQueue1") Queue queue){
return BindingBuilder.bind(queue).to(topicExchange).with("*.orange.*");
}
@Bean("topicQueueBinding2")
public Binding topicQueueBinding2(@Qualifier("topicExchange") TopicExchange topicExchange, @Qualifier("topicQueue2") Queue queue){
return BindingBuilder.bind(queue).to(topicExchange).with("*.*.rabbit");
}
@Bean("topicQueueBinding3")
public Binding topicQueueBinding3(@Qualifier("topicExchange") TopicExchange topicExchange, @Qualifier("topicQueue2") Queue queue){
return BindingBuilder.bind(queue).to(topicExchange).with("lazy.#");
}
}
生产者
import com.example.rabbitmqspringboot.constant.Constants;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/producer")
@RestController
public class ProducerController {
// 引入RabbitTemplate 这是Spring Boot提供的RabbitMQ客户端相关操作
@Autowired
private RabbitTemplate rabbitTemplate;
// 工作模式的生产者代码
@RequestMapping("/work")
public String work(){
for (int i = 0; i < 10; i++) {
//使用内置交换机, RoutingKey 和队列名称一致
rabbitTemplate.convertAndSend("", Constants.WORK_QUEUE, "hello spring amqp: work..."+i);
}
return "发送成功";
}
@RequestMapping("/fanout")
public String fanout(){
rabbitTemplate.convertAndSend(Constants.FANOUT_EXCHANGE,"", "hello spring amqp:fanout...");
return "发送成功";
}
// 路由键是 orange black
@RequestMapping("/direct/{routingKey}")
public String direct(@PathVariable("routingKey") String routingKey){
rabbitTemplate.convertAndSend(Constants.DIRECT_EXCHANGE, routingKey, "hello spring amqp:direct, my routing key is "+routingKey);
return "发送成功";
}
// 路由键 *.orange.* *.*.rabbit lazy.#
@RequestMapping("/topic/{routingKey}")
public String topic(@PathVariable("routingKey") String routingKey){
rabbitTemplate.convertAndSend(Constants.TOPIC_EXCHANGE, routingKey, "hello spring amqp:topic, my routing key is "+routingKey);
return "发送成功";
}
}
消费者
订阅发布模式
import com.example.rabbitmqspringboot.constant.Constants;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class FanoutListener {
@RabbitListener(queues = Constants.FANOUT_QUEUE1)
public void queueListener1(String message){
System.out.println("队列["+Constants.FANOUT_QUEUE1+"] 接收到消息:" +message);
}
@RabbitListener(queues = Constants.FANOUT_QUEUE2)
public void queueListener2(String message){
System.out.println("队列["+Constants.FANOUT_QUEUE2+"] 接收到消息:" +message);
}
}
路由模式
import com.example.rabbitmqspringboot.constant.Constants;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class DirectListener {
@RabbitListener(queues = Constants.DIRECT_QUEUE1)
public void queueListener1(String message){
System.out.println("队列["+Constants.DIRECT_QUEUE1+"] 接收到消息:" +message);
}
@RabbitListener(queues = Constants.DIRECT_QUEUE2)
public void queueListener2(String message){
System.out.println("队列["+Constants.DIRECT_QUEUE2+"] 接收到消息:" +message);
}
}
通配符模式
import com.example.rabbitmqspringboot.constant.Constants;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class TopicListener {
@RabbitListener(queues = Constants.TOPIC_QUEUE1)
public void queueListener1(String message){
System.out.println("队列["+Constants.TOPIC_QUEUE1+"] 接收到消息:" +message);
}
@RabbitListener(queues = Constants.TOPIC_QUEUE2)
public void queueListener2(String message){
System.out.println("队列["+Constants.TOPIC_QUEUE2+"] 接收到消息:" +message);
}
}