开始
解决原始代码没法修改,原始代码没法入参。调用放的入参不一样。就是解决两边业务逻辑不一致的问题。
根据接收的队列的不同 用不同的方法去调用。
代码实战
之前我们接收消息处理把这里给接收掉了
回调是走的这个莱姆达表达式。这个莱姆达表达式才是我们实际要用的。
回调接入Spring Boot
我们起名字叫做handleMessage,参数我们定义为byte类型的,下面原来第一行代码我们就不需要了。删除即可。
这个readValue要抛异常,我们声明在方法声明上。
log我们转换成一个String类型输出。
上面的handleMessage这是我们老的java的方式,这里直接删除,不用了。
这里有自动注入。
这个删除
调用回调方法
这里调用orderMessageService的handleMessage方法,然后把message.getBody给传进去。
启动测试
收到了消息并且调用了。handleMessage方法
这是一种很好的方法,我们在MessageListener里面,再去调用handleMessage方法。这么写稍微有点不优雅。
config类是做设置用的,我们直接在里面写了业务逻辑。
怎么做到不写这种显示的调用?但是它还可以调用到我们handleMessage里面的方法?我们先把下面那块代码注释掉。
使用MessageListenerAdapter
MessageListenerAdapter 里面可以设置Delegate,我们直接设置orderMessageService
设置MessageListener直接传入messageListenerAdapter
设置直接通过一行代码。把orderMessageService传到构造函数里面去。直接可以设置代理。
启动测试
是什么原理呢?
进入MessageListenerAdapter
首先它继承了
抽象类又实现了 ChannelAwareMessageListener
这是我们之前注释的代码 先放开,就是我们之前用到的ChnnelAwareMessageListener
所以MessageListenerAdapter 就是实现了ChannelAwareMessageListener
那么我们实现了ChannelAwareMessageListener 不应该是调用onMessage方法吗?
怎么会调用到我们业务代码的handleMessage方法呢?
再次进去到这个类
这个类里面一定有一个onMessage方法
首先是获取到delegate方法
判断这个代理,是不是ChannelAwareMessageListener的类或者子类。
这个类是我们自己写的,没有任何的继承
这两个if它都走不进去
继续往下走
返回了默认的监听器的方法。
这个属性,它是一个常量,她叫做handleMessage。它把这个字符串往回返。
就是我们的业务代码的方法名称一定叫做handleMessage的原因了
传入这个方法名,调用这个方法
它新建了一个类叫做MethodInvoker
这个工具类是帮助我们调用具体的方法的
调用这个工具的invoke
最后还是做了反射
用了反射,直接调用我们需要的类
高级用法
如果有人把方法名称拼错了,少拼写了字母
这一行也注释掉
HashMap我们知道就塞一条数据 那么就设置初始值为8,因为hashMap在达到容量的一定范围。默认的是初始容量的0.8,进行扩容。扩容的时候要占据很大的系统资源。非常消耗系统资源。所以这里我们设置上最终需要的容量的0.75倍以上就可以。如果要塞100个东西 那么至少是128。128的0.75倍能不能装下100个? 这里直接256得了。这是很大厂面试要考你的东西。
把队列和方法名 加到map里面。
测试
成功被调用。
这里的onMessage方法会最终调用业务方法
方法名字叫什么呢?是从这里得出来的getListenerMethodName
我们刚才把if给忽略了。直接返回了默认的方法名
我们刚才设置的hashMap
这样就走中间这部分的逻辑
这个消息是从哪个队列收来的
这个就是获取到的hashMap里面的方法名称
拿到了方法名,最终调用
不同队列用不同的方法去处理