之前我们已经学习了2种交换机类型了,今天我们再来学习一下主题交换机类型,主题交换机类型的核心思想就是可以通过正则表达式的方式,将queue 和 exchange绑定。我们直接代码演示:
package com.lwl.rabbitmq.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.lwl.rabbitmq.constant.Constants;
/**
* 发送消息 配置发送消息的队列queue
* @author lwl
* @create 2018年8月10日 下午2:37:38
* @version 1.0
*/
@Configuration
public class SendMessageConfig {
@Bean
public Queue topicQueue() {
return new Queue(Constants.TOPIC_QUEUE);
}
@Bean
public Queue topicQueue2() {
return new Queue(Constants.TOPIC_QUEUE_TWO);
}
@Bean
TopicExchange exchange() {
return new TopicExchange(Constants.TOPIC_NAME);
}
/**
* 使用主题交换机,
* 将队列Constants.TOPIC_QUEUE与exchange绑定,binding_key为topic.queue.key,就是完全匹配
* @param topicQueue
* @param exchange
* @return
* @author lwl
* @create 2019年6月14日 上午10:51:21
*/
@Bean
Binding bindingExchangeMessage(Queue topicQueue, TopicExchange exchange) {
return BindingBuilder.bind(topicQueue).to(exchange).with(Constants.ROUTING_KEY);
}
/**
* 使用主题交换机,routekey
* 将队列Constants.TOPIC_QUEUE_TWO与exchange绑定,binding_key为topic.*.#,模糊匹配
* @param topicQueue2
* @param exchange
* @return
* @author lwl
* @create 2019年6月14日 上午10:51:21
*/
@Bean
Binding bindingExchangeMessage2(Queue topicQueue2, TopicExchange exchange) {
return BindingBuilder.bind(topicQueue2).to(exchange).with(Constants.ROUTING_KEY_TWO);
}
}
这里我们有2个队列名称,一个是通过完全匹配的方式,绑到exchange上,一个是通过模糊 也就是正则表达式方式绑到exchange上。
看一下生产者:
package com.lwl.rabbitmq.producer;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.lwl.rabbitmq.constant.Constants;
/**
* 生成者
* @author lwl
* @create 2019年6月14日 上午10:56:41
* @version 1.0
*/
@Component
public class Producer {
@Autowired
private AmqpTemplate template;
/**
* 使用主题交换机
* @param message
* @author lwl
* @create 2019年6月14日 上午10:54:54
*/
public void send(Object message){
template.convertAndSend(Constants.TOPIC_NAME,Constants.ROUTING_KEY,message);
}
/**
* 如果routingKey 推送到对应的queue中
* @param routingKey
* @param message
* @author lwl
* @create 2019年6月14日 下午2:56:39
*/
public void send(String routingKey,Object message){
template.convertAndSend(Constants.TOPIC_NAME,routingKey,message);
}
}
第一个推送的方法,使用的routingKey是完全匹配模式,第二个可以是自定义模式
看一下消费者:
package com.lwl.rabbitmq.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import com.lwl.rabbitmq.constant.Constants;
/**
* 消费者 使用模糊匹配模式
* @author lwl
* @create 2019年6月14日 上午10:57:11
* @version 1.0
*/
@Component
@RabbitListener(queues = Constants.TOPIC_QUEUE_TWO)
public class TopicConsumer {
@RabbitHandler
public void process(String hello) {
System.out.println();
System.out.println("-----------------------客户端 1 收到数据 -----------------------");
System.out.println(Constants.TOPIC_QUEUE_TWO+ " --> Receiver1 : " + hello);
System.out.println();
}
}
package com.lwl.rabbitmq.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import com.lwl.rabbitmq.constant.Constants;
/**
* 消费者 使用完全匹配模式
* @author lwl
* @create 2019年6月14日 上午10:57:11
* @version 1.0
*/
@Component
@RabbitListener(queues = Constants.TOPIC_QUEUE)
public class TopicConsumer3 {
@RabbitHandler
public void process(String hello) {
System.out.println();
System.out.println("-----------------------客户端 3 收到数据 -----------------------");
System.out.println(Constants.TOPIC_QUEUE+ " --> Receiver3 : " + hello);
System.out.println();
}
}
接下来我们看一下测试类:
@Test
public void send() {
String message = "topic send message ";
producer.send(message);
}
结果分析:
-----------------------客户端 3 收到数据 -----------------------
topic_queue --> Receiver3 : topic send message
-----------------------客户端 1 收到数据 -----------------------
topic_queue_2 --> Receiver1 : topic send message
由于调用的方法的路由routingkey是:topic.queue.key,那么绑定主题交换机对应的queue有2个,
一个是topic_queue (完全匹配),另一个是topic_queue_2(他的路由key是:topic.*.#)模糊匹配上了
测试方法2:
@Test
public void send2() {
String message = "topic send message 2222222222";
String routingKey = "topic.queue.two";
producer.send(routingKey , message);
}
测试结果分析:
-----------------------客户端 1 收到数据 -----------------------
topic_queue_2 --> Receiver1 : topic send message 2222222222
由于发送的路由key是:topic.queue.two,不能匹配到topic.queue.key,所以队列topic_queue收不到
而topic_queue_2(他的路由key是:topic.*.#)模糊匹配上了