routing,路由模式其实也是使用了交换机,和发布订阅不同的是我们这次使用direct类型的交换机,然后们再加上一些路由key的配置,这样交换机根据路由规则将消息推送到指定的队列里。

    在common模块下新建一个【Constant3】存储本次的常量:

    1. package com.zhaoxy.study.common;
    2. /**
    3. * rabbitmq,路由模式
    4. */
    5. public interface Constant3 {
    6. String exchangeName = "study_direct_exchange";
    7. String routeName1 = "route_name_info";
    8. String routeName2 = "route_name_error";
    9. String queueName1 = "Constant3-Queue_1";
    10. String queueName2 = "Constant3-Queue_2";
    11. }

    然后修改消费者的监听程序:

    1. package com.zhaoxy.mqconsumer;
    2. import com.zhaoxy.study.common.Constant3;
    3. import org.springframework.amqp.rabbit.annotation.Exchange;
    4. import org.springframework.amqp.rabbit.annotation.Queue;
    5. import org.springframework.amqp.rabbit.annotation.QueueBinding;
    6. import org.springframework.amqp.rabbit.annotation.RabbitListener;
    7. import org.springframework.stereotype.Component;
    8. @Component
    9. public class MqConsumerListener {
    10. @RabbitListener(
    11. // bindings 支持多个配置
    12. bindings = {
    13. // 队列绑定,绑定交换机【Constant3.exchangeName】数据推送到这个队列的【Constant3.queueName1】
    14. @QueueBinding(value = @Queue(value = Constant3.queueName1, durable = "true"),
    15. exchange = @Exchange(value = Constant3.exchangeName),
    16. // 声明我只接收路由key为【Constant3.routeName1, Constant3.routeName2】的数据
    17. key = {Constant3.routeName1, Constant3.routeName2})
    18. }
    19. )
    20. public void listener1(String message) throws InterruptedException {
    21. System.out.println("接收到了【"+Constant3.queueName1+"】队列的消息:" + message);
    22. }
    23. @RabbitListener(bindings = {
    24. @QueueBinding(value = @Queue(value = Constant3.queueName2, durable = "true"),
    25. exchange = @Exchange(value = Constant3.exchangeName),
    26. key = {Constant3.routeName1})})
    27. public void listener2(String message) throws InterruptedException {
    28. System.out.println("接收到了【"+Constant3.queueName2+"】队列的消息:" + message);
    29. }
    30. }

    这里就需要注意了,【listener1】方法接收了队列里两种路由key的数据,而【listener2】只接收一种路由key的数据,然后我们在生产者模拟交换机往两个队列里,都推送两个路由key,看控制台输出的情况。

    1. package com.zhaoxy.mqprod;
    2. import com.zhaoxy.study.common.Constant3;
    3. import org.springframework.amqp.rabbit.core.RabbitTemplate;
    4. import org.springframework.stereotype.Component;
    5. import javax.annotation.PostConstruct;
    6. import javax.annotation.Resource;
    7. import java.util.UUID;
    8. @Component
    9. public class MqProdService {
    10. @Resource
    11. private RabbitTemplate rabbitTemplate;
    12. /**
    13. * 消息生产者,用途就是每次项目启动后都生成一次消息。
    14. *
    15. * 一遍两遍三四遍,五遍六遍七八遍,
    16. * 九遍十遍十一遍,学习完毕全不见。
    17. */
    18. @PostConstruct
    19. public void prodMessage(){
    20. // 模式3,给指定交换机发送一个uuid,带有路由规则推送到队列中
    21. for (int i = 0; i < 5; i++) {
    22. rabbitTemplate.convertAndSend(Constant3.exchangeName, Constant3.routeName1, "Constant3.routeName1的"+UUID.randomUUID());
    23. rabbitTemplate.convertAndSend(Constant3.exchangeName, Constant3.routeName2, "Constant3.routeName2的"+UUID.randomUUID());
    24. }
    25. }
    26. }

    先启动consumer服务,再启动生产者服务,查看consumer的控制台输出情况:
    image.png
    可以看到【listener1】确实可以接收到两个路由key的数据,而【listener2】却只有一个路由key的,且绝对不会消费到另一个路由key的。

    这种模式适用于对同一主体数据但不同状态或类型数据的处理,例如某一业务有三种情况,那么三种情况就对应了三种不同的逻辑处理,对应的消费者只需要关注自己这种类型情况的逻辑即可。