开始

可以把消息从字节数组转换成我们需要的数据类型。
image.png

消息使用java对象,不使用Byte数组了。
image.png
jackjson是我们平常用的ObjectMap。我们现在收发消息就是用的ObjectMap。这个map就是jackjson这包来的。jsckjson是专门做json处理的类。jackjson2json就是json对象的转换。

image.png

image.png

代码实战

处理消息的时候 ,原来我们是Byte类型的,现在我们想直接用DTO类型的object对象。
image.png

image.png
打印dto
image.png

设置的时候,没有做其他任何的设置,那么 直接调用肯定就会抛出异常
image.png
发请求测试。
image.png
它用别的类型的参数,调用目标方法失败。
image.png
默认这种原生的方式就是Byte数组的形式。
image.png

image.png
参数是MessageConverter我们先写上去,然后找它的实现
image.png
ctrl+at+b
image.png
image.png
直接new 一个它的实现类。
image.png

运行测试

image.png

还是报错了
image.png
Jackson2Josn默认的转换结果是一个HashMap。它默认会将json的消息转换成HashMap来取调用我们的目标方法
image.png
但是我们的handleMessage 它需要的是OrderMessasgeDTO对象。
image.png

对ClassMapper进行设置
image.png
new 一个 classMapper
image.png
重点是toClass方法、它把MessageProperties也就是消息的属性 传给你,让你自己去判断这个消息应该是一个什么类型的。然后把这个消息的类型返回回去就可以了。
image.png
我们的消息类型是OrderMessageDTO类型,所以我们直接返回这个类型。
image.png

image.png
这里是老代码的实现方式,可以先new一个ObjectMapper然后再转换成OrderMessageDTO类型。这种方式可以实现,但是不够优雅
image.png
我们还是用这种高级的用法
image.png

测试

image.png

image.png

别的方式做消息的转换

image.png
需要的额参数类型。这个地方用的不多。
image.png
这个类是个抽象的,我们需要找一个它的实现类
image.png

ctrl+alt+b直接跳到了唯一的实现。如果有多个的话,它会让你自己选。
image.png
image.png
image.png
这种方式限制你的消息里面必须含有,消息它的类型属性。在整个大的工程或者微服务体系中,各个微服务之间它对一个消息的dto的类型是不一样的,而且对方可能是个go服务,我是个java服务。互相不可能在消息的属性里面还带着这个消息的类型。他的类型是我们本地定义的OrderMessageDTO可能在对方那里就不是一个类型。

我们还是用上面这种方式
image.png

不同类型调用不同转换器

image.png
image.png

根据消息属性的不同 调用不同的messageConverter。这个类也用的很少 。

image.png

源码,原理解析

我们设置的MessageConverter 是Jackson2JsonMessageConverter 设置到了adapter里面 ,那么它是怎么用起来的呢?
image.png

image.png
有消息过来 也是首先调用它的onMessage方法。
image.png

最关键的一行代码是这里、这里拿到需要调用的方法名。
image.png
还有invokeListenerMethod这两个方法。这是真正调用方法
image.png
我们上课节跳过了这个方法。extract是提取的的意思。提取后的消息,它的变量名是convertedMessage。就是已经被转化过的消息。所以消息转换一定是在这个extractMessage里面。
image.png
跳到了它的父类
image.png
image.png
返回了messageConverter这个成员。

image.png
这个成员就是我们设置的Jackson2JsonMessageConverter

image.png
拿到converter后,调用它的fromMessage方法
image.png

fromMessage本身没有fromMessage方法,那么就肯定在父类里面
image.png
进入他的父类 找到了方法
image.png
又调用了它的重载方法。重载多了一个参数叫做ConversionHint 转换的线索。
image.png
这个message进来后,它做什么了?它调用了doFromMessage
image.png

进入doFromMessage方法
image.png
先判断了TypeMapper
image.png
然后又判断convertHint,这里也没进去。
image.png
再往下就到了getClassMapper了。我们给他设置了classMapper了。
image.png
这是我们设置的classMapper。这里我们写了个匿名类。
image.png
classMapper不为null,我们就走到了最后这里
image.png

调用classMapper的toClass方法
image.png
toClass方法被我们重写了,永远返回OrderMessageDTO这个class
image.png
他拿到了class就是目标的class
image.png
将字节数组转化为对象
image.png
最后调用的是ObjectMapper.readValue 最后的最后还是调用的jackson这个mapper的readValue方法。这行代码和我们之前接收到消息的时候,对消息的转换过程一模一样。
image.png
我们原来的消息,之前我们注释掉了。这里暂时放开。
image.png
还是要注释掉
image.png

这些所谓的高级的框架,做了整个架子,最终调用的也是最基础的代码。和我们之前的业务实现是一样的。
为什么要切到spring boot平台上呢?因为她用了很高级的模式,让我们方便的去使用它,用起来不需要关心底层的实现。

因为我们知道objectMapper.readValue它会抛异常,它抛了异常怎么办?或者你传的类名不对怎么办?或者是这个channel或者connection还没有启动怎么办?这些问题是spring的amqp包帮我们处理好的。
image.png

研究源码提高个人水平!

结束