开始
可以把消息从字节数组转换成我们需要的数据类型。
消息使用java对象,不使用Byte数组了。
jackjson是我们平常用的ObjectMap。我们现在收发消息就是用的ObjectMap。这个map就是jackjson这包来的。jsckjson是专门做json处理的类。jackjson2json就是json对象的转换。
代码实战
处理消息的时候 ,原来我们是Byte类型的,现在我们想直接用DTO类型的object对象。
打印dto
设置的时候,没有做其他任何的设置,那么 直接调用肯定就会抛出异常
发请求测试。
它用别的类型的参数,调用目标方法失败。
默认这种原生的方式就是Byte数组的形式。
参数是MessageConverter我们先写上去,然后找它的实现
ctrl+at+b
直接new 一个它的实现类。
运行测试
还是报错了
Jackson2Josn默认的转换结果是一个HashMap。它默认会将json的消息转换成HashMap来取调用我们的目标方法
但是我们的handleMessage 它需要的是OrderMessasgeDTO对象。
对ClassMapper进行设置
new 一个 classMapper
重点是toClass方法、它把MessageProperties也就是消息的属性 传给你,让你自己去判断这个消息应该是一个什么类型的。然后把这个消息的类型返回回去就可以了。
我们的消息类型是OrderMessageDTO类型,所以我们直接返回这个类型。
这里是老代码的实现方式,可以先new一个ObjectMapper然后再转换成OrderMessageDTO类型。这种方式可以实现,但是不够优雅
我们还是用这种高级的用法
测试
别的方式做消息的转换
需要的额参数类型。这个地方用的不多。
这个类是个抽象的,我们需要找一个它的实现类
ctrl+alt+b直接跳到了唯一的实现。如果有多个的话,它会让你自己选。
这种方式限制你的消息里面必须含有,消息它的类型属性。在整个大的工程或者微服务体系中,各个微服务之间它对一个消息的dto的类型是不一样的,而且对方可能是个go服务,我是个java服务。互相不可能在消息的属性里面还带着这个消息的类型。他的类型是我们本地定义的OrderMessageDTO可能在对方那里就不是一个类型。
我们还是用上面这种方式
不同类型调用不同转换器
根据消息属性的不同 调用不同的messageConverter。这个类也用的很少 。
源码,原理解析
我们设置的MessageConverter 是Jackson2JsonMessageConverter 设置到了adapter里面 ,那么它是怎么用起来的呢?
有消息过来 也是首先调用它的onMessage方法。
最关键的一行代码是这里、这里拿到需要调用的方法名。
还有invokeListenerMethod这两个方法。这是真正调用方法
我们上课节跳过了这个方法。extract是提取的的意思。提取后的消息,它的变量名是convertedMessage。就是已经被转化过的消息。所以消息转换一定是在这个extractMessage里面。
跳到了它的父类
返回了messageConverter这个成员。
这个成员就是我们设置的Jackson2JsonMessageConverter
拿到converter后,调用它的fromMessage方法
fromMessage本身没有fromMessage方法,那么就肯定在父类里面
进入他的父类 找到了方法
又调用了它的重载方法。重载多了一个参数叫做ConversionHint 转换的线索。
这个message进来后,它做什么了?它调用了doFromMessage
进入doFromMessage方法
先判断了TypeMapper
然后又判断convertHint,这里也没进去。
再往下就到了getClassMapper了。我们给他设置了classMapper了。
这是我们设置的classMapper。这里我们写了个匿名类。
classMapper不为null,我们就走到了最后这里
调用classMapper的toClass方法
toClass方法被我们重写了,永远返回OrderMessageDTO这个class
他拿到了class就是目标的class
将字节数组转化为对象
最后调用的是ObjectMapper.readValue 最后的最后还是调用的jackson这个mapper的readValue方法。这行代码和我们之前接收到消息的时候,对消息的转换过程一模一样。
我们原来的消息,之前我们注释掉了。这里暂时放开。
还是要注释掉
这些所谓的高级的框架,做了整个架子,最终调用的也是最基础的代码。和我们之前的业务实现是一样的。
为什么要切到spring boot平台上呢?因为她用了很高级的模式,让我们方便的去使用它,用起来不需要关心底层的实现。
因为我们知道objectMapper.readValue它会抛异常,它抛了异常怎么办?或者你传的类名不对怎么办?或者是这个channel或者connection还没有启动怎么办?这些问题是spring的amqp包帮我们处理好的。
研究源码提高个人水平!