routing,路由模式其实也是使用了交换机,和发布订阅不同的是我们这次使用direct类型的交换机,然后们再加上一些路由key的配置,这样交换机根据路由规则将消息推送到指定的队列里。
在common模块下新建一个【Constant3】存储本次的常量:
package com.zhaoxy.study.common;/*** rabbitmq,路由模式*/public interface Constant3 {String exchangeName = "study_direct_exchange";String routeName1 = "route_name_info";String routeName2 = "route_name_error";String queueName1 = "Constant3-Queue_1";String queueName2 = "Constant3-Queue_2";}
然后修改消费者的监听程序:
package com.zhaoxy.mqconsumer;import com.zhaoxy.study.common.Constant3;import org.springframework.amqp.rabbit.annotation.Exchange;import org.springframework.amqp.rabbit.annotation.Queue;import org.springframework.amqp.rabbit.annotation.QueueBinding;import org.springframework.amqp.rabbit.annotation.RabbitListener;import org.springframework.stereotype.Component;@Componentpublic class MqConsumerListener {@RabbitListener(// bindings 支持多个配置bindings = {// 队列绑定,绑定交换机【Constant3.exchangeName】数据推送到这个队列的【Constant3.queueName1】@QueueBinding(value = @Queue(value = Constant3.queueName1, durable = "true"),exchange = @Exchange(value = Constant3.exchangeName),// 声明我只接收路由key为【Constant3.routeName1, Constant3.routeName2】的数据key = {Constant3.routeName1, Constant3.routeName2})})public void listener1(String message) throws InterruptedException {System.out.println("接收到了【"+Constant3.queueName1+"】队列的消息:" + message);}@RabbitListener(bindings = {@QueueBinding(value = @Queue(value = Constant3.queueName2, durable = "true"),exchange = @Exchange(value = Constant3.exchangeName),key = {Constant3.routeName1})})public void listener2(String message) throws InterruptedException {System.out.println("接收到了【"+Constant3.queueName2+"】队列的消息:" + message);}}
这里就需要注意了,【listener1】方法接收了队列里两种路由key的数据,而【listener2】只接收一种路由key的数据,然后我们在生产者模拟交换机往两个队列里,都推送两个路由key,看控制台输出的情况。
package com.zhaoxy.mqprod;import com.zhaoxy.study.common.Constant3;import org.springframework.amqp.rabbit.core.RabbitTemplate;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;import javax.annotation.Resource;import java.util.UUID;@Componentpublic class MqProdService {@Resourceprivate RabbitTemplate rabbitTemplate;/*** 消息生产者,用途就是每次项目启动后都生成一次消息。** 一遍两遍三四遍,五遍六遍七八遍,* 九遍十遍十一遍,学习完毕全不见。*/@PostConstructpublic void prodMessage(){// 模式3,给指定交换机发送一个uuid,带有路由规则推送到队列中for (int i = 0; i < 5; i++) {rabbitTemplate.convertAndSend(Constant3.exchangeName, Constant3.routeName1, "Constant3.routeName1的"+UUID.randomUUID());rabbitTemplate.convertAndSend(Constant3.exchangeName, Constant3.routeName2, "Constant3.routeName2的"+UUID.randomUUID());}}}
先启动consumer服务,再启动生产者服务,查看consumer的控制台输出情况:
可以看到【listener1】确实可以接收到两个路由key的数据,而【listener2】却只有一个路由key的,且绝对不会消费到另一个路由key的。
这种模式适用于对同一主体数据但不同状态或类型数据的处理,例如某一业务有三种情况,那么三种情况就对应了三种不同的逻辑处理,对应的消费者只需要关注自己这种类型情况的逻辑即可。
