SpringAMQP订阅模型
交换机类型一般分为
- Fanout 广播模型
- Direct 路由模型
- Topic 话题
#### SpringAMQP演示FanoutExchang使用
Fanout就是将消息发送跟跟他绑定的队列中 - 子啊consumer服务中,利用代码声明队列,交换机,将两者绑定
@Configuration
public class FanoutExchangeConfig {
@Bean
public FanoutExchange fanoutExchange(){
// 声明交换机名称
return new FanoutExchange("itcast.fanout");
}
//声明消息队列
@Bean
public Queue queue1(){
return new Queue("fanout.queue1");
}
//绑定交换机和queue1队列
@Bean
public Binding binding1(Queue queue1,FanoutExchange fanoutExchange){
return BindingBuilder.bind(queue1).to(fanoutExchange);
}
//声明消息队列
@Bean
public Queue queue2(){
return new Queue("fanout.queue2");
}
//绑定交换机和queue2队列
@Bean
public Binding binding2(Queue queue2,FanoutExchange fanoutExchange){
return BindingBuilder.bind(queue2).to(fanoutExchange);
}
}
- 在consumer服务中编写两个消费方法,分别监听fanout1和fanout2
@RabbitListener(queues = "fanout.queue1")
public void fanoutQueue1(String msg){
System.out.println("fanout.queuq1的消息"+msg);
}
@RabbitListener(queues = "fanout.queue2")
public void fanoutQueue2(String msg){
System.out.println("fanout.queuq2的消息"+msg);
}
- 在publisher中写测试方法,向itcast.fanout发送消息
@Test
public void testFanoutExchange(){
// 交换机名称
String exchangeName ="itcast.fanout";
// 消息
String message = "Hello,every one";
rabbitTemplate.convertAndSend(exchangeName,"",message);
}
发送消息之后 与交换机绑定的两个队列都获取到了消息
Direct交换机模型
- 每一个Queue都与Exchange设置一个BingingKEy
- 发布消息时,指定消息的RoutingKey
- Exchange将消息路由到BindingKey与消息RoutingKey一致的队列
将消息转发给与他的route一致的队列
声明交换机的方式有两种
- 用@Configuration配置类添加Bean来声明交换机和队列
- 通过@RabbitListener()直接声明绑定并监听
// 声明Direct队列
@RabbitListener(bindings = @QueueBinding(
// 声明的队列
value = @Queue("direct.queue1"),
// 声明的交换机 和类型
exchange = @Exchange(name = "itcast.direct",type = ExchangeTypes.DIRECT),
// 声明的key 发布者发布对应的key会让与发布者的key对应的队列来处理
key = {"red","blue"}
))
public void direct1Exchange(String msg){
System.out.println("监听到的数据--->"+msg);
}
// 声明Direct队列
@RabbitListener(bindings = @QueueBinding(
// 声明的队列
value = @Queue("direct.queue2"),
// 声明的交换机 和类型
exchange = @Exchange(name = "itcast.direct",type = ExchangeTypes.DIRECT),
// 声明的key 发布者发布对应的key会让与发布者的key对应的队列来处理
key = {"red","yellow"}
))
public void direct2Exchange(String msg){
System.out.println("监听到的数据--->"+msg);
}
监听执行后就会有这些队列
- 发送内容
@Test
public void testDirectExchange(){
// 交换机名称
String exchangeName ="itcast.direct";
// 消息
String message = "Hello,blue";
// 指定对应的key 发送与其队列key匹配的队列
rabbitTemplate.convertAndSend(exchangeName,"red",message);
}
TopicExchange交换机
与DirectExchange类似,区别在于routingKey必须是多个单词的列表,用
(.)分隔
可以使用通配符
#:代表0个和多个单词
*:代表一个单词
编写java代码
// 声明Topic队列
@RabbitListener(bindings = @QueueBinding(
value = @Queue("topic.queue1"),
exchange = @Exchange(value = "itcast.topic",type = ExchangeTypes.TOPIC),
key = {"china.#"}
))
public void testTopicQueue1(String msg){
System.out.println("china.#拿到的消息"+msg);
}
// 声明Topic队列
@RabbitListener(bindings = @QueueBinding(
value = @Queue("topic.queue2"),
exchange = @Exchange(value = "itcast.topic",type = ExchangeTypes.TOPIC),
key = {"#.news"}
))
public void testTopicQueue2(String msg){
System.out.println("#.news拿到的消息"+msg);
}
发布者代码
@Test
public void testTopicExchange(){
// 交换机名称
String exchangeName ="itcast.topic";
// 消息
String message = "Hello,Hello";
// 只需要注意key的传值即可
rabbitTemplate.convertAndSend(exchangeName,"china.weather",message);
}
消息转换器
//在配置类@Configuration声明队列
@Bean
public Queue objectQueue2(){
return new Queue("object.queue");
}
// 发送object对象
@Test
public void testMessageExchange(){
Map<String,Object> map = new HashMap<>();
map.put("name","刘阳");
map.put("age","18");
rabbitTemplate.convertAndSend("object.queue",map);
}
得到的内容为java自带的序列化我们看不懂,因为AMQP自带的是使用java的序列化
我们要使用消息转换器覆盖掉原来的序列化
- 引入依赖
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.10</version>
</dependency>
添加配置Bean
@Bean
public MessageConverter messageConverter(){
// 消息转换器
return new Jackson2JsonMessageConverter();
}
发送消息就可以完整的看到对象内容