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 类型交换机 的消息,实现 ​通配符路由​ 的灵活消息分发模式

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

相关推荐
SimonKing3 小时前
OpenCode AI辅助编程,不一样的编程思路,不写一行代码
java·后端·程序员
FastBean3 小时前
Jackson View Extension Spring Boot Starter
java·后端
Seven974 小时前
剑指offer-79、最⻓不含重复字符的⼦字符串
java
皮皮林55113 小时前
Java性能调优黑科技!1行代码实现毫秒级耗时追踪,效率飙升300%!
java
冰_河14 小时前
QPS从300到3100:我靠一行代码让接口性能暴涨10倍,系统性能原地起飞!!
java·后端·性能优化
桦说编程16 小时前
从 ForkJoinPool 的 Compensate 看并发框架的线程补偿思想
java·后端·源码阅读
躺平大鹅18 小时前
Java面向对象入门(类与对象,新手秒懂)
java
用户83071968408219 小时前
RabbitMQ vs RocketMQ 事务大对决:一个在“裸奔”,一个在“开挂”?
后端·rabbitmq·rocketmq
初次攀爬者19 小时前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq