消息队列2-SpringBoot操作RabbitMQ

文章目录

  • [一. 公共流程](#一. 公共流程)
    • [1. 引入依赖](#1. 引入依赖)
    • [2. 配置application.yml参数](#2. 配置application.yml参数)
  • [二. Work Queue(工作队列模式)](#二. Work Queue(工作队列模式))
    • [1. 声明队列](#1. 声明队列)
    • [2. 发送消息](#2. 发送消息)
    • [3. 监听(消费)消息](#3. 监听(消费)消息)
  • [三. 发布订阅模式](#三. 发布订阅模式)
    • [1. 声明队列](#1. 声明队列)
    • [2. 声明交换机](#2. 声明交换机)
    • [3. 交换机绑定队列](#3. 交换机绑定队列)
    • [4. 发送消息](#4. 发送消息)
    • [5. 监听消息](#5. 监听消息)
  • [四. 路由模式](#四. 路由模式)
    • [1. 声明队列与交换机](#1. 声明队列与交换机)
    • [2. 交换机绑定队列](#2. 交换机绑定队列)
    • [3. 发送消息](#3. 发送消息)
    • [4. 监听消息](#4. 监听消息)

这里只举几个典型的模式来进行SpringBoot操作RabbitMQ的演示, 对于类似的模式, 这里会省略

一. 公共流程

1. 引入依赖

对于SpringBoot项目, 这应该是老生常谈的步骤, 先引入starter依赖

java 复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp-test</artifactId>
            <scope>test</scope>
        </dependency>

2. 配置application.yml参数

我这里使用的docker启动的RabbitMQ服务, 所以映射到了本地

java 复制代码
spring:
  application:
    name: spring-rabbitmq-demo
  rabbitmq:
    host: localhost
    port: 5672
    username: admin
    password: admin
    virtual-host: ran

二. Work Queue(工作队列模式)

1. 声明队列

将队列的声明交给Spring进行管理, 这里使用Bean来修饰

java 复制代码
package com.ran.jh.rabbitmq.config;

import com.ran.jh.rabbitmq.constant.Constants;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ran
 * Date: 2026-03-24
 * Time: 15:06
 */
@Configuration
public class RabbitMQConfig {
    // 声明(创建)工作模式队列
    @Bean("workQueue")
    public Queue workQueue() {
        return QueueBuilder.durable(Constants.WORK_QUEUE).build();
    }
}

2. 发送消息

这里使用web服务来控制消息发送, 并且发送消息时, 使用的默认交换机, 默认交换机是与每个队列隐性绑定的, 转发消息时, 只需要RoutingKey和队列保持一致

java 复制代码
package com.ran.jh.rabbitmq.controller;

import com.ran.jh.rabbitmq.constant.Constants;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ran
 * Date: 2026-03-24
 * Time: 15:10
 */
@RequestMapping("/producer")
@RestController
public class ProducerController {
    @Autowired
    private RabbitTemplate rabbitTemplate; // 获取模版
    @RequestMapping("/work")
    public String work() {
        for (int i = 0; i < 5; i++) {
            rabbitTemplate.convertAndSend("", Constants.WORK_QUEUE,"hello, spring amqp 工作队列模式...");
        }
        return "发送成功";
    }

}

3. 监听(消费)消息

使用Listener注解, 来定义监听哪个队列, 并且可以给修饰的方法传入从队列中收到的参数

常见参数:
1. String 用来接收消息的主体
2. Message(org.springframework.amqp.core.Message) 用来接收消息的所有参数, 包括deliveryTag, 队列等信息
3. Channel(com.rabbitmq.client.Channel) 这是RabbitMQ的通道对象, 可以用来开启confirm模式等高级功能

java 复制代码
package com.ran.jh.rabbitmq.listener;

import com.rabbitmq.client.Channel;
import com.ran.jh.rabbitmq.constant.Constants;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ran
 * Date: 2026-03-25
 * Time: 13:30
 */
@Component
public class WorkListeners {
    @RabbitListener(queues = Constants.WORK_QUEUE)
    public void RabbitListener1(Message message, Channel channel) {
        System.out.println("Listener1, 消息所有参数message: " + message +" , 通道Channel: " + channel);
    }

    @RabbitListener(queues = Constants.WORK_QUEUE)
    public void RabbitListener2(String msg) {
        System.out.println("Listener2, 消息主体内容msg: " + msg);
    }
}

三. 发布订阅模式

1. 声明队列

java 复制代码
    // 声明订阅模式队列
    @Bean("fanoutQueue1")
    public Queue fanoutQueue1() {
        return QueueBuilder.durable(Constants.FANOUT_QUEUE1).build();
    }
    @Bean("fanoutQueue2")
    public Queue fanoutQueue2() {
        return QueueBuilder.durable(Constants.FANOUT_QUEUE2).build();
    }

2. 声明交换机

java 复制代码
    // 声明交换机
    @Bean("fanoutExchange")
    public FanoutExchange fanoutExchange() {
        return ExchangeBuilder.fanoutExchange(Constants.FANOUT_EXCHANGE).durable(true).build();
    }

3. 交换机绑定队列

绑定时, 需要交换机和队列的名称, 因此在用@Bean创建队列时, 就需要指定他们的名称

java 复制代码
    // 声明绑定关系
    @Bean("fanoutQueueBindExchange1")
    public Binding fanoutQueueBindExchange1(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange, @Qualifier("fanoutQueue1") Queue queue) {
        return BindingBuilder.bind(queue).to(fanoutExchange);
    }
    @Bean("fanoutQueueBindExchange2")
    public Binding fanoutQueueBindExchange2(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange, @Qualifier("fanoutQueue2") Queue queue) {
        return BindingBuilder.bind(queue).to(fanoutExchange);
    }

4. 发送消息

java 复制代码
    @RequestMapping("/fanout")
    public String fanout() {
        for (int i = 0; i < 5; i++) {
            rabbitTemplate.convertAndSend(Constants.FANOUT_EXCHANGE,"","hello, spring amqp 发布订阅模式..." + i);
        }
        return "发送成功";
    }

5. 监听消息

java 复制代码
package com.ran.jh.rabbitmq.listener;

import com.ran.jh.rabbitmq.constant.Constants;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ran
 * Date: 2026-03-25
 * Time: 13:30
 */
@Component
public class FanoutListeners {
    @RabbitListener(queues = Constants.FANOUT_QUEUE1)
    public void RabbitListener1(String msg) {
        System.out.println("Listener1," + "队列[" + Constants.FANOUT_QUEUE1 + "] 消息主体内容msg: " + msg);
    }

    @RabbitListener(queues = Constants.FANOUT_QUEUE2)
    public void RabbitListener2(String msg) {
        System.out.println("Listener2," + "队列[" + Constants.FANOUT_QUEUE2 + "] 消息主体内容msg: " + msg);

    }
}

四. 路由模式

接下来我们按照下图来声明BindingKey和RoutingKey, 同时又因为通配符模式相对于路由模式, 只是交换机类型变了, 且匹配规则不同, 因此不再赘述通配符模式

1. 声明队列与交换机

交换机类型要声明为Direct

java 复制代码
    @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();
    }

2. 交换机绑定队列

java 复制代码
    // 声明绑定关系
    @Bean("directQueueBindExchange1")
    public Binding directQueueBindExchange1(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue1") Queue queue) {
        return BindingBuilder.bind(queue).to(directExchange).with("orange");
    }
    @Bean("directQueueBindExchange2")
    public Binding directQueueBindExchange2(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue2") Queue queue) {
        return BindingBuilder.bind(queue).to(directExchange).with("orange");
    }
    @Bean("directQueueBindExchange3")
    public Binding directQueueBindExchange3(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue2") Queue queue) {
        return BindingBuilder.bind(queue).to(directExchange).with("black");
    }

3. 发送消息

这里我们将RoutingKey放到请求路径中, 并且参数从路径中来获取, 这里使用@PathVariable注解

java 复制代码
    // 路由模式
    @RequestMapping("/direct/{routingKey}")
    public String direct(@PathVariable("routingKey") String routingKey) {
        rabbitTemplate.convertAndSend(Constants.DIRECT_EXCHANGE,routingKey,"hello, spring amqp 路由模式..." + " ,routingKey: " + routingKey);
        return "发送成功, routingKey: " + routingKey;
    }

4. 监听消息

java 复制代码
package com.ran.jh.rabbitmq.listener;

import com.ran.jh.rabbitmq.constant.Constants;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ran
 * Date: 2026-03-25
 * Time: 13:30
 */
@Component
public class DirectListeners {
    @RabbitListener(queues = Constants.DIRECT_QUEUE1)
    public void RabbitListener1(String msg) {
        System.out.println("Listener1," + "队列[" + Constants.DIRECT_QUEUE1 + "] 消息主体内容msg: " + msg);
    }

    @RabbitListener(queues = Constants.DIRECT_QUEUE2)
    public void RabbitListener2(String msg) {
        System.out.println("Listener2," + "队列[" + Constants.DIRECT_QUEUE2 + "] 消息主体内容msg: " + msg);

    }
}
相关推荐
lay_liu2 小时前
springboot和springframework版本依赖关系
java·spring boot·后端
تچ快乐杂货店يچ2 小时前
基于前后端分离的在线考试系统(微服务架构 + RBAC权限 + AI助手)
java·vue.js·spring boot·spring cloud·微服务·架构·typescript
yashuk2 小时前
RabbitMQ高级特性----生产者确认机制
分布式·rabbitmq
sjmaysee3 小时前
Springboot中使用Elasticsearch(部署+使用+讲解 最完整)
spring boot·elasticsearch·jenkins
六义义3 小时前
SpringBoot 超详细全解(入门 + 实战 + 原理 + 面试)
java·spring boot·面试
太阳之神aboluo3 小时前
RabbitMQ
java·分布式·spring·rabbitmq·java-rabbitmq
计算机学姐3 小时前
基于SpringBoot+Vue的智能民宿预定游玩系统【AI智能客服+数据可视化】
java·vue.js·spring boot·后端·mysql·spring·信息可视化
wenlonglanying3 小时前
springcloud springboot nacos版本对应
spring boot·spring·spring cloud
小江的记录本3 小时前
【泛型】泛型:泛型擦除、通配符、上下界限定
java·windows·spring boot·后端·spring·maven·mybatis