在Fanout模式中,一条消息,会被所有订阅的队列都消费。但是,在某些场景下,我们希望消息被指定的队列消费。这时就要用到Direct类型的Exchange。

在Direct模型下:

  • 队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)
  • 消息的发送方在 向 Exchange发送消息时,也必须指定消息的 RoutingKey
  • Exchange不再把消息交给每一个绑定的队列,而是根据消息的RoutingKey进行判断,只有队列的Routingkey与消息的 Routingkey完全一致,才会接收到消息。

案例

  1. 利用@RabbitListener声明Exchange、Queue、RoutingKey
  2. 在consumer服务中,编写两个消费者方法,分别监听direct.queue1和direct.queue2
  3. 在publisher中编写测试方法,向itcast. direct发送消息

image-20210717170223317.png

1.引入依赖

Basic Queue

2.基于注解声明交换机和队列并接收消息

基于@Bean的方式声明队列和交换机比较麻烦,Spring还提供了基于注解方式来声明。
在consumer的SpringRabbitListener中添加两个消费者,同时基于注解来声明队列和交换机:

  1. package cn.itcast.mq.listener;
  2. import org.springframework.amqp.core.ExchangeTypes;
  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 SpringRabbitListener {
  10. @RabbitListener(bindings = @QueueBinding(
  11. value = @Queue(name = "direct.queue1"),
  12. exchange = @Exchange(name = "itcast.direct", type = ExchangeTypes.DIRECT),
  13. key = {"red", "blue"}
  14. ))
  15. public void listenDirectQueue1(String msg){
  16. System.out.println("消费者接收到direct.queue1的消息:【" + msg + "】");
  17. }
  18. @RabbitListener(bindings = @QueueBinding(
  19. value = @Queue(name = "direct.queue2"),
  20. exchange = @Exchange(name = "itcast.direct", type = ExchangeTypes.DIRECT),
  21. key = {"red", "yellow"}
  22. ))
  23. public void listenDirectQueue2(String msg){
  24. System.out.println("消费者接收到direct.queue2的消息:【" + msg + "】");
  25. }
  26. }

3.发送消息

在publisher服务的SpringAmqpTest类中添加测试方法:

  1. @Test
  2. public void testSendDirectExchange() {
  3. // 交换机名称
  4. String exchangeName = "itcast.direct";
  5. // 消息
  6. String message = "红色警报!日本乱排核废水,导致海洋生物变异,惊现哥斯拉!";
  7. // 发送消息
  8. rabbitTemplate.convertAndSend(exchangeName, "red", message);
  9. }

因为两个队列都绑定了red的key,所以发消息给带有red key的队列,两个消费者都能拿到消息
image.png