应用侧
经过学习发现传递的都是字符串对象,但是微服务里可不会只有字符串才对,常用的我直接传个实体类dto,就像是redis一样嘛,那么MQ是否也支持呢?
在common里创建一个消息对象类,若想要能传输这种实体类,那么类必须要实例化:
package com.zhaoxy.study.common;import lombok.Data;import java.io.Serializable;/*** 以对象的方式来传输消息*/@Datapublic class MsgObj implements Serializable {private String id;private String name;}
如果这个实体类没有实例化,那么会报错,因为对象无法转换成二进制对象。
消费者只需要把参数类型改成对应对象就可以了:
package com.zhaoxy.mqconsumer;import com.zhaoxy.study.common.Constant1;import com.zhaoxy.study.common.MsgObj;import org.springframework.amqp.rabbit.annotation.Queue;import org.springframework.amqp.rabbit.annotation.RabbitListener;import org.springframework.stereotype.Component;@Componentpublic class MqConsumerListener {@RabbitListener(queuesToDeclare = @Queue(Constant1.queueName))public void listener(MsgObj obj){System.out.println("接收到了生产者的消息:" + obj);}}
生产者也是同理:
package com.zhaoxy.mqprod;import com.zhaoxy.study.common.Constant1;import com.zhaoxy.study.common.MsgObj;import org.springframework.amqp.rabbit.core.RabbitTemplate;import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;import javax.annotation.Resource;import java.util.UUID;@Componentpublic class MqProdService {@Resourceprivate RabbitTemplate rabbitTemplate;/*** 消息生产者,用途就是每次项目启动后都生成一次消息。** 一遍两遍三四遍,五遍六遍七八遍,* 九遍十遍十一遍,学习完毕全不见。*/@PostConstructpublic void prodMessage(){// 模式1,给指定队列发送一个uuidfor (int i = 0; i < 5; i++) {MsgObj msgObj = new MsgObj();msgObj.setId(UUID.randomUUID().toString());msgObj.setName("name-"+i);rabbitTemplate.convertAndSend(Constant1.queueName, msgObj);}}}
然后先重启消费者,再启动生产者,查看控制台输出情况:
服务侧
在MQ的控制台查看队列里的消息,如果没有做处理的话,拿到的就是经过base64加密后的字符串:
这种数据我们并无法知晓内容,得在common模块中增加config类,使得各module都使用统一的序列化方式:
package com.zhaoxy.study.common;import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;import org.springframework.amqp.support.converter.MessageConverter;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class MqConfig {// 消息转换配置@Beanpublic MessageConverter jsonMessageConverter(){return new Jackson2JsonMessageConverter();}}
但是这样有一个问题,就是这种的配置并不会真的生效,因为consumer和prod引入依赖后,并不会加载到它里面的config配置,想要让它生效,就需要用到另一个特殊但是极为常用的技术。
就是spring.factories文件,在springboot应用中被广泛流传,为什么引入一个依赖后只需要配置好服务地址就能生效?就是因为在引入包里就有spring.factories文件,使得配置的类得以在项目启动中被加载执行。
做法很简单,在common模块下的resources文件夹内,先新建一个【META-INF】文件夹,再下一层新建【spring.factories】文件。
在文件里需要写上核心内容:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.zhaoxy.study.common.MqConfig
如果有多个,那么就把各个类以英文逗号相隔,如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.zhaoxy.study.common.MqConfig,com.zhaoxy.study.common.MqConfig,# 等等~~~~~
然后只重启生产者服务即可,不启动consumer是为了避免消息消费了看不到了,启动后查看控制台里,获取消息看看结果如何:
