Topic类型的ExchangeDirect相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routingkey 的时候使用通配符!
Routingkey 一般都是有一个或多个单词组成,多个单词之间以**.**分割,例如: item.insert

通配符规则:

  • #:匹配一个或多个词
  • *:匹配不多不少恰好1个词

举例:
item.#:能够匹配item.spu.insert 或者 item.spu
item.*:只能匹配item.spu

图示:

image-20210717170705380.png
解释:

  • Queue1:绑定的是china.#,因此凡是以china.开头的routingkey 都会被匹配到。包括china.newschina.weather
  • Queue2:绑定的是#.news ,因此凡是以 .news结尾的 routingkey 都会被匹配。包括china.newsjapan.news

    案例

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


image-20210717170829229.png

1.引入依赖

Basic Queue

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

  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 = "topic.queue1"),
  12. exchange = @Exchange(name = "itcast.topic", type = ExchangeTypes.TOPIC),
  13. key = "china.#"
  14. ))
  15. public void listenTopicQueue1(String msg){
  16. System.out.println("消费者接收到topic.queue1的消息:【" + msg + "】");
  17. }
  18. @RabbitListener(bindings = @QueueBinding(
  19. value = @Queue(name = "topic.queue2"),
  20. exchange = @Exchange(name = "itcast.topic", type = ExchangeTypes.TOPIC),
  21. key = "#.news"
  22. ))
  23. public void listenTopicQueue2(String msg){
  24. System.out.println("消费者接收到topic.queue2的消息:【" + msg + "】");
  25. }
  26. }

3.发送消息

  1. /**
  2. * topicExchange
  3. */
  4. @Test
  5. public void testSendTopicExchange() {
  6. // 交换机名称
  7. String exchangeName = "itcast.topic";
  8. // 消息
  9. String message = "喜报!孙悟空大战哥斯拉,胜!";
  10. // 发送消息
  11. rabbitTemplate.convertAndSend(exchangeName, "china.news", message);
  12. }

因为发送者带的key china.news两个队列的key china.##.news 都匹配,所以两个消费者都拿到了消息
image.png