7.RabbitMQ系列之topic主题交换器
topic主题交换器它根据在队列绑定的路由键和路由模式通配符匹配将消息路由到队列。
生产者在消息头中添加路由键并将其发送到主题交换器。 收到消息后,exchange尝试将路由键与绑定到它的所有队列的绑定路由模式匹配。 如果找到匹配,则将消息路由到其路由模式匹配的队列,如果未找到匹配,则忽略该消息
Routing key: 它是单词列表,由句点 (.) 分隔,例如“asia.china.beijing”
Routing Pattern: 它是在绑定队列时指定的模式,它是单词和通配符的列表,如*和#,由句点 (.) 分隔。 通配符的使用如下:
*: 用于匹配路由键中特定位置的单词,例如“asia.china.*”的路由模式将匹配第一个单词是asia而第二个单词的路由键单词是china,例如asia.china.beijing和asia.china.nanjing。
# :- 用于匹配零个或多个单词,例如asia.china.#的路由模式将匹配以asia.china开头的路由键,例如“asia.china”和 “亚洲.中国.北京”。
1.完整代码示例
- 新增TopicExchangeConfig.java配置文件
@Configuration
public class TopicExchangeConfig {
@Bean
public TopicExchange topic() {
return new TopicExchange("topic");
}
private static class ConsumerConfig {
@Bean
public Queue topicAutoDeleteQueue1() {
return new AnonymousQueue();
}
@Bean
public Queue topicAutoDeleteQueue2() {
return new AnonymousQueue();
}
@Bean
public Binding topicBinding1(TopicExchange topic, Queue topicAutoDeleteQueue1) {
return BindingBuilder.bind(topicAutoDeleteQueue1).to(topic).with("asia.china.*");
}
@Bean
public Binding topicBinding2(TopicExchange topic, Queue topicAutoDeleteQueue2) {
return BindingBuilder.bind(topicAutoDeleteQueue2).to(topic).with("asia.china.#");
}
}
}
- 新增生产者
@Component
public class TopicSender {
private RabbitTemplate rabbitTemplate;
public TopicSender(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
public void send() {
rabbitTemplate.convertAndSend("topic", "asia.china.beijing", "asia.china.beijing");
rabbitTemplate.convertAndSend("topic", "asia.china.nanjing", "asia.china.nanjing");
rabbitTemplate.convertAndSend("topic", "asia.china", "asia.china");
}
}
- 消费者
@Component
public class TopicReceiver {
@RabbitListener(queues = "#{topicAutoDeleteQueue1.name}")
public void receive1(String in) {
System.out.println("临时队列1接收到消息:" + in);
}
@RabbitListener(queues = "#{topicAutoDeleteQueue2.name}")
public void receive2(String in) {
System.out.println("临时队列2接收到消息:" + in);
}
}
- 单元测试
@SpringBootTest
public class RabbitTest {
@Autowired
private TopicSender topicSender;
@Test
public void testTopicSender() {
topicSender.send();
}
}
可以看到对于#模式只有队列2接收到asia.china消息