需求:测试利用SpringAMQP发送对象类型的消息
- 声明一个队列,名为object.queue
- 编写单元测试,向队列中直接发送一条消息,消息类型为Map
- 在控制台查看消息,总结你能发现的问题
1、声明队列
@Bean
public Queue fanoutQueue(){
return new Queue("object.queue");
}
2、发送消息
@Test
void sendObject(){
Map<String, Object> msg = new HashMap<>(2);
msg.put("name","jack");
msg.put("age",21);
rabbitTemplate.convertAndSend("object.queue",msg);
}
3、控制台结果
问题总结:
原因:因为发送的消息是Object类型,源码会将Object做序列化操作转换成二进制,最后使用JDK自带的对象输出流写到队列里面。
Spring的对消息对象的处理是orq.springframeworkamap.supportconverter,MessageConverter来处理的。而默认实现是SimpleMessageConverter,基于JDK的ObjectOutputStream完成序列化。
JDK序列化导致的问题:
- 转码后消息内容所占空间变大
- 代码可读性差
- 存在安全风险
4、配置消息转换器
- 采用JSON序列化代替默认的JDK序列化,在消息生产者跟消费者的pom.xml文件中添加
<!--Jackson-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
- 消息生产者跟消费者中都要配置MessageConverter
@Bean
public MessageConverter jacksonMessageConvertor(){
return new Jackson2JsonMessageConverter();
}
5、消费者消费
@RabbitListener(queues = "object.queue") //监听的队列:object.queue
public void listenTopicQueue2(Map<String,Object> msg) {
System.out.println("消费者2 收到消息:【"+msg+"】");
}
6、结果展示
控制台输出