Spring Boot+RabbitMQ 实战:4 种交换机模式(Work/Fanout/Direct/Topic)保姆级实现

RabbitMQ 的实现

Spring AMQP

Spring 提供了RabbitMQ 开发的封装,Spring AMQP通过集成Spring生态,大幅简化了消息队列

引入依赖

java 复制代码
<!--Spring MVC相关依赖--> 
<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>
<!--RabbitMQ相关依赖--> 
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

配置 Constants

java 复制代码
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";
 
}

配置 Config

java 复制代码
@Configuration
public class RabbitMQConfig {
    //work_queue
    @Bean("workQueue")
    public Queue workQueue(){
        return QueueBuilder.durable(Constants.WORK_QUEUE).build();
    }
 
    //fanout_queue
    @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).build();
    }
    @Bean("bindingFanoutQueue1")
    public Binding bindingFanoutQueue1(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange,@Qualifier("fanoutQueue1")  Queue queue){
        return BindingBuilder.bind(queue).to(fanoutExchange);
    }
    @Bean("bindingFanoutQueue2")
    public Binding bindingFanoutQueue2(@Qualifier("fanoutExchange") FanoutExchange fanoutExchange,@Qualifier("fanoutQueue2")  Queue queue){
        return BindingBuilder.bind(queue).to(fanoutExchange);
    }
 
 
    // direct_queue
    @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).build();
    }
    @Bean("bindingDirectQueue1")
    public Binding bindingDirectQueue1(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue1") Queue queue){
        return BindingBuilder.bind(queue).to(directExchange()).with("a");
    }
    @Bean("bindingDirectQueue2")
    public Binding bindingDirectQueue2(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue2") Queue queue){
        return BindingBuilder.bind(queue).to(directExchange()).with("b");
    }
    @Bean("bindingDirectQueue3")
    public Binding bindingDirectQueue3(@Qualifier("directExchange") DirectExchange directExchange, @Qualifier("directQueue2") Queue queue){
        return BindingBuilder.bind(queue).to(directExchange()).with("c");
    }
 
 
    @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).build();
    }
    @Bean("bindingTopicQueue1")
    public Binding bindingTopicQueue1(@Qualifier("topicExchange") TopicExchange topicExchange, @Qualifier("topicQueue1") Queue queue){
        return BindingBuilder.bind(queue).to(topicExchange).with("*.x.*");
    }
    @Bean("bindingTopicQueue2")
    public Binding bindingTopicQueue2(@Qualifier("topicExchange") TopicExchange topicExchange, @Qualifier("topicQueue2") Queue queue){
        return BindingBuilder.bind(queue).to(topicExchange).with("*.*.y");
    }
    @Bean("bindingTopicQueue3")
    public Binding bindingTopicQueue3(@Qualifier("topicExchange") TopicExchange topicExchange, @Qualifier("topicQueue2") Queue queue){
        return BindingBuilder.bind(queue).to(topicExchange).with("xy'.#");
    }
    
}

可以通过配置 Config 一次性大量的声明,队列、交换机、绑定关系等,大幅度缩减了频繁创建文件的次数

ProducerController

java 复制代码
@RestController
@RequestMapping("/producer")
public class ProducerController {
    @Autowired
    private RabbitTemplate rabbitTemplate;
 
 
    @RequestMapping("/work")
    public String work(){
        for (int i = 0; i <10 ; i++) {
            rabbitTemplate.convertAndSend("", Constants.WORK_QUEUE,"hello work queue" + i);
        }
        return "发送成功";
    }
    @RequestMapping("/fanout")
    public String fanout(){
        for (int i = 0; i <10 ; i++) {
            rabbitTemplate.convertAndSend(Constants.FANOUT_EXCHANGE,"","hello fanout queue" + i);
        }
        return "发送成功";
    }
    @RequestMapping("/direct/{routingKey}")
    public String direct(@PathVariable("routingKey") String routingKey){
        rabbitTemplate.convertAndSend(Constants.DIRECT_EXCHANGE,routingKey,"hello direct this is routingKey " + routingKey);
        return "发送成功";
    }
    @RequestMapping("/topic/{routingKey}")
    public String topic(@PathVariable("routingKey") String routingKey){
        rabbitTemplate.convertAndSend(Constants.TOPIC_EXCHANGE,routingKey,"hello topic " + routingKey);
        return "发送成功";
    }
}

这是一个基于Spring Boot的RabbitMQ消息生产者控制器(ProducerController),用于向RabbitMQ消息队列发送消息。它实现了四种常见的消息队列模式,通过HTTP接口触发消息发送

WorkListener

java 复制代码
@Component
public class WorkListener {
    @RabbitListener( queues = Constants.WORK_QUEUE )
    public void workListener1(String message) {
        System.out.println("队列["+Constants.WORK_QUEUE+"] 接收到消息:" + message);
    }
    @RabbitListener( queues = Constants.WORK_QUEUE )
    public void workListener2(String message) {
        System.out.println("队列["+Constants.WORK_QUEUE+"] 接收到消息:" + message);
    }
}

@RabbitListener 不仅可用于方法,还可用于类级别。当标注在处理方法时如上图代码所示,当标注在类时,需要搭配 @RabbitHandler 使用,将 @RabbitHandler 标注在类的方法上

FanOutListener

java 复制代码
@Component
public class DirectListener {
    @RabbitListener(queues = Constants.DIRECT_QUEUE1)
    public void queueListener1(String msg) throws InterruptedException {
        System.out.println("队列["+Constants.DIRECT_QUEUE1+"] 接收到消息:" + msg);
    }
 
    @RabbitListener(queues = Constants.DIRECT_QUEUE2)
    public void queueListener2(String msg) throws InterruptedException {
        System.out.println("队列["+Constants.DIRECT_QUEUE2+"] 接收到消息:" + msg);
    }
}

outListener 是一个基于 Spring AMQP 的消息消费者组件,专门用于处理 ​Fanout 类型交换机 的消息。它通过**@RabbitListener** 注解监听两个不同的队列,实现 ​广播模式​ 的消息消费

DirectListener

java 复制代码
@Component
public class DirectListener {
    @RabbitListener(queues = Constants.DIRECT_QUEUE1)
    public void queueListener1(String msg) throws InterruptedException {
        System.out.println("队列["+Constants.DIRECT_QUEUE1+"] 接收到消息:" + msg);
    }
 
    @RabbitListener(queues = Constants.DIRECT_QUEUE2)
    public void queueListener2(String msg) throws InterruptedException {
        System.out.println("队列["+Constants.DIRECT_QUEUE2+"] 接收到消息:" + msg);
    }
}

DirectListener 专门用于处理 ​Direct 类型交换机 的消息,实现​路由键精准匹配​的消息分发模式

TopicsListener

java 复制代码
public class TopicsListener {
    @RabbitListener(queues = Constants.TOPIC_QUEUE1)
    public void topicListener1(String message){
        System.out.println( "队列["+Constants.TOPIC_QUEUE1+"] 接收到消息:" + message);
 
    }
 
    @RabbitListener(queues = Constants.TOPIC_QUEUE2)
    public void topicListener2(String message){
        System.out.println( "队列["+Constants.TOPIC_QUEUE2+"] 接收到消息:" + message);
 
    }
}

TopicsListener 专门用于处理 ​Topic 类型交换机 的消息,实现 ​通配符路由​ 的灵活消息分发模式

希望这份博客能够帮助到你。如果有其他需要修改或添加的地方,请随时告诉我。

相关推荐
Slow菜鸟9 小时前
Java后端常用技术选型 |(四)微服务篇
java·分布式
武子康9 小时前
Java-168 Neo4j CQL 实战:WHERE、DELETE/DETACH、SET、排序与分页
java·开发语言·数据库·python·sql·nosql·neo4j
Filotimo_9 小时前
SpringBoot3入门
java·spring boot·后端
通往曙光的路上9 小时前
SpringIOC-注解
java·开发语言
zhangbaolin9 小时前
深度智能体的中间件
中间件·langchain·大模型·深度智能体
一 乐10 小时前
校园墙|校园社区|基于Java+vue的校园墙小程序系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端·小程序
TT哇10 小时前
【面经 每日一题】面试题16.25.LRU缓存(medium)
java·算法·缓存·面试
青云交10 小时前
Java 大视界 -- 基于 Java 的大数据联邦学习在跨行业数据协同创新中的实践突破
java·分布式计算·隐私保护·apache flink·大数据联邦学习·跨行业数据协同·安全通信
合作小小程序员小小店10 小时前
桌面开发,在线%考试管理%系统,基于eclipse,java,swing,mysql数据库。
java·数据库·mysql·eclipse·jdk
oioihoii10 小时前
C/C++混合项目中的头文件管理:.h与.hpp的分工与协作
java·c语言·c++