topic模式也称为主题模式,相对于routing模式最大的好处就是他多了一种匹配模式的路由
工作流程图:
绑定键binding key也必须是这种形式。以特定路由键发送的消息将会发送到所有绑定键与之匹配的队列中。但绑定键有两种特殊的情况:
①*(星号)仅代表一个单词
②#(井号)代表任意个单词
我们就拿上面的图解释,.orange.能匹配 a.orange.a,b.orange.a,aa.orange.bb等等
lay.#能匹配的就多了,他只要一lay.开头的都匹配,他可以匹配lay.a,lay.a.b,lay.b.c等。
这样是不是很方便,比如我们想将log的发给q1队列,其他的发给q2,那么我们只需要定义log.#、或者log.*,那么你发送给q1队列的数据就是log日志的消息。
1、队列、交换机的声明和绑定
public class TopmicMqConfig {
@Bean(name = "message111")
public Queue queueMessage() {
return new Queue("topic.message111");
}
@Bean(name = "messages111")
public Queue queueMessages() {
return new Queue("topic.messages111");
}
@Bean
public TopicExchange exchange() {
return new TopicExchange("exchange111");
}
@Bean
Binding bindingExchangeMessage(@Qualifier("message111") Queue queueMessage, TopicExchange exchange) {
return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message111");
}
@Bean
Binding bindingExchangeMessages(@Qualifier("messages111") Queue queueMessages, TopicExchange exchange) {
return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");//*表示一个词,#表示零个或多个词
}
}
如上:我们定义了两个队列message111和messages111,message111匹配的是精准的topic.message111,而messages111匹配的是只要是以top开头的则都会匹配到
2、消息生产者和消费者
生产者:
@Controller
@RequestMapping("topic")
public class SenderTopic {
private Logger logger= LoggerFactory.getLogger(SenderTopic.class);
@Autowired
private AmqpTemplate rabbitTemplate;
@RequestMapping("sendMessage")
public void sendMessage() {
logger.info("调用接口/topic/sendMessage");
rabbitTemplate.convertAndSend("exchange111", "topic.message111", "hello, rabbit!");//第一种情况
// rabbitTemplate.convertAndSend("exchange111", "topic.messages111", "hello, rabbit!");//第二种情况
}
消费者:
@Component
public class ReceiverTopic {
@RabbitListener(queues="topic.message111") //监听器监听指定的Queue
public void process1(String str) {
System.out.println("message:"+str);
}
@RabbitListener(queues="topic.messages111") //监听器监听指定的Queue
public void process2(String str) {
System.out.println("messages:"+str);
}
}
3、测试
利用postman测试生产者的第一种情况:
第一种情况,routingKey设置的是topic.message111,两个队列都匹配到了,所以都收到了消息
第二种情况:
第二种情况,routingKey设置的是topic.messages111,队列message111只能精准匹配topic.message111,无法匹配到topic.messages111(注意messages最后的s),所以只有messages111收到了消息,因为提配的是以topic.开头的全部