pom.xml依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
三种交换机:
DirectExchange:
直连型交换机,根据消息携带的路由键将消息投递给对应队列。
大致流程,有一个队列绑定到一个直连交换机上,同时赋予一个路由键 routing key 。
然后当一个消息携带着路由值为X,这个消息通过生产者发送给交换机时,交换机就会
根据这个路由值X去寻找绑定值也是X的队列。
FanoutExchange:
扇型交换机,这个交换机没有路由键概念,就算你绑了路由键也是无视的。 这个交换
机在接收到消息后,会直接转发到绑定到它上面的所有队列.
Topic Exchange:
主题交换机,这个交换机其实跟直连交换机流程差不多,但是它的特点就是在它的路由键和绑定键之间是有规则的。
简单地介绍下规则:
‘*’ (星号) 用来表示一个单词 (必须出现的)
‘#’ 井号 用来表示任意数量(零个或多个)单词
三种交换机代码差不多,就先粘贴TopicExchange的:
package com.thunisoft.xuexi.rabbitmq.topicExchange;
import com.thunisoft.xuexi.rabbitmq.util.RabbitMQConsts;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author ZhuRuiLin
* @Description:
* @date 2020/12/1
**/
@Configuration
public class TestTopicExchange {
@Autowired
private AmqpAdmin admin;
@Bean
public Queue firstQueue(){
return new Queue(RabbitMQConsts.TEST_TOPIC_QUEUE1);
}
@Bean
public Queue secondQueue(){
return new Queue((RabbitMQConsts.TEST_TOPIC_QUEUE2));
}
@Bean
public TopicExchange exchange(){
return new TopicExchange(RabbitMQConsts.TEST_TOPIC_EXCHANGE);
}
// 将firstQueue() 和 exchange() 绑定,并且绑定的键值是"topic.#
// 只要消息的路由键是topic.开头的 都会分发到firestQueu()里
@Bean
public Binding binging1(){
return BindingBuilder.bind(firstQueue()).to(exchange()).with(RabbitMQConsts.TEST_TOPIC_ROUTING_KEY1);
}
// 将secondQueue 和 exchange() 绑定 并且绑定的键值是 topic.queue2
// 只有消息的路由键是topic.queue2 ,才会分发到secondQueue 队列
@Bean
public Binding binding2(){
return BindingBuilder.bind(secondQueue()).to(exchange()).with(RabbitMQConsts.TEST_TOPIC_QUEUE2);
}
@Bean
public void create(){
admin.declareExchange(exchange());
admin.declareQueue(firstQueue());
admin.declareQueue(secondQueue());
admin.declareBinding(binging1());
admin.declareBinding(binding2());
}
}
然后生产者写在了controller层中,
@GetMapping("/topic1")
public ResultVO provider1(@RequestParam String content){
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
String createTime = sdf.format(new Date());
Map<String,Object> map = new HashMap<>();
map.put(RabbitMQConsts.MESSAGE_ID,UUIDHelper.generatorID());
map.put(RabbitMQConsts.MESSAGE_DATA,content);
map.put(RabbitMQConsts.CREATE_TIME,createTime);
rabbitTemplate.convertAndSend(RabbitMQConsts.TEST_TOPIC_EXCHANGE,RabbitMQConsts.TEST_TOPIC_QUEUE1,map);
return new ResultVO(true,"成功发送",null);
}
@GetMapping("/topic2")
public ResultVO provider2(@RequestParam String content){
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
String createTime = sdf.format(new Date());
Map<String,Object> map = new HashMap<>();
map.put(RabbitMQConsts.MESSAGE_ID,UUIDHelper.generatorID());
map.put(RabbitMQConsts.MESSAGE_DATA,content);
map.put(RabbitMQConsts.CREATE_TIME,createTime);
rabbitTemplate.convertAndSend(RabbitMQConsts.TEST_TOPIC_EXCHANGE,RabbitMQConsts.TEST_TOPIC_QUEUE2,map);
return new ResultVO(true,"成功发送",null);
其次消费者的代码:
package com.thunisoft.xuexi.rabbitmq.rabbitweb;
import com.thunisoft.xuexi.rabbitmq.util.RabbitMQConsts;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author ZhuRuiLin
* @Description:
* @date 2020/12/1
**/
@Component
public class RabbitMQConsumer {
@RabbitListener(queues = RabbitMQConsts.TEST_DIRECT_QUEUE)
@RabbitHandler
public void process(Map message){
System.out.println("RabbitMQConsumer中的 process 方法消费:"+message.toString());
}
@RabbitListener(queues = RabbitMQConsts.TEST_TOPIC_QUEUE1)
@RabbitHandler
public void process1(Map message){
System.out.println("RabbitMQConsumer中的 process1 方法消费:"+message.toString());
}
@RabbitListener(queues = RabbitMQConsts.TEST_TOPIC_QUEUE2)
@RabbitHandler
public void process2(Map message){
System.out.println("RabbitMQConsumer中的 process2 方法消费:"+message.toString());
}
}
我是使用postman调用生产者,在调用topic1的接口的时候,控制台只会打印一条,也就是process1 的消费,调用topic2的时候,控制台则会打印两条消费输出,验证了TopicExchange的路由规则。