文章目录
RabbitMQ第五个实操小案例——主题交换机(TopicExchange)RabbitMQ第五个实操小案例——主题交换机(TopicExchange)
TopicExchange
和DirectExchange
这两种交换机非常相似,Topic
类型的Exchange
与Direct
相比,都是可以根据RoutingKey
把消息路由到不同的队列。只不过Topic
类型的RoutingKey必须是多个单词的列表,并用.
隔开。
例如:
china.news:中国新闻的异步通讯
china.weather:中国天气的异步通信
japan.news:小日子新闻的异步通讯
japan.weather:小日子天气的异步通讯
这个东西很有意思,他是可以使用通配符的,其中
#:代表0个或多个单词
*:代表1个单词
如此,如果我们现在要监听的是中国的所有消息,那么我们的routingKey就是china.#
,如果我们想监听的是所有国家的新闻,那么我们的routingKey就是*.news
。
废话少说,代码来一波:
配置pom导入依赖跟配置yaml文件环境的代码就不说了。
步骤一、使用@RabbitListener写我们的监听器。
@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "topic.queue1"),exchange = @Exchange(name = "exchange.topic", type = ExchangeTypes.TOPIC),key = {"china.#"}))public void listenTopicQueue1(String msg){System.out.println("监听到的来自中国的消息为【"+msg+"】");}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "topic.queue2"),exchange = @Exchange(name = "exchange.topic", type = ExchangeTypes.TOPIC),key = "#.news"))public void listenTopicQueue2(String msg){System.out.println("监听到的来自全世界的新闻为【"+msg+"】");}
步骤二、编写发布者,发送消息
@Testpublic void testTopicExchange(){//交换机的名称String exchangeName = "exchange.topic";//消息String chinaNews = "这是一条来自中国的新闻!";String chinaWeather = "这是一条来自中国的天气预报!";String japanNews = "这是一条来自小日子的新闻!";String japanWeather ="这是一条来自小日子的天气预报!";//发送消息rabbitTemplate.convertAndSend(exchangeName, "china.news", chinaNews);rabbitTemplate.convertAndSend(exchangeName, "china.weather", chinaWeather);rabbitTemplate.convertAndSend(exchangeName, "japan.news", japanNews);rabbitTemplate.convertAndSend(exchangeName, "japan.weather", japanWeather);}
发布完成后,我们来看一下效果:
可以看到
1、监听china.#
的监听者成功监听了来自中国的新闻和天气预报。
2、监听#.news
的监听者监听到了来自全世界的新闻。
这种写法的好处就是,以后假如我们多了来自中国的其他东西,比如china.science,以及加拿大的新闻,我们的监听者都不需要修改任何代码。代码走一波,我们修改一下我们的发布者的代码。
@Testpublic void testTopicExchange(){//交换机的名称String exchangeName = "exchange.topic";//消息String chinaNews = "这是一条来自中国的新闻!";String chinaWeather = "这是一条来自中国的天气预报!";String japanNews = "这是一条来自小日子的新闻!";String japanWeather ="这是一条来自小日子的天气预报!";//新增加的消息String chinaScience = "这是一条来自中国的科学!";String canadaNews = "这是一条来自加拿大的新闻!";//发送消息rabbitTemplate.convertAndSend(exchangeName, "china.news", chinaNews);rabbitTemplate.convertAndSend(exchangeName, "china.weather", chinaWeather);rabbitTemplate.convertAndSend(exchangeName, "japan.news", japanNews);rabbitTemplate.convertAndSend(exchangeName, "japan.weather", japanWeather);//额外发送的消息rabbitTemplate.convertAndSend(exchangeName, "china.science", chinaScience);rabbitTemplate.convertAndSend(exchangeName, "canada.news", canadaNews);}
为了方便看,我还把监听实际新闻的sout改成了err(变成红色),我们来看一下最新的效果:
可以看到,这里计算我们新加了其他的消息,我们的china.#
也可以正常接收routingKey是以china开头的所有消息,而我们的#.news
也可以正常接收routingKey是以news结尾的所有消息。