知其然要知其所以然,刚好趁这个机会把博客重新捡起来。

之前项目的目的是处理dubbo泛化调用的返回值,处理LocalDateTim,LocalDate,LocalTime。转换为时间戳。

一、如何泛化调用

使用泛化调用 | Apache Dubbohttps://dubbo.apache.org/zh/docs/advanced/generic-reference/官网已经给出例子了。那我们要解析一般的dubbo在调用的时候在做什么。

泛化调用过程中我们作为一个客户端,会连接到注册中心,拿到指定的api接口服务以及这个接口服务下面的所有方法。

然后找到我们指定的接口方法发起invoker调用。

注意:ReferenceConfig是一个特别重的实例,它里面封装了所有与注册中心及服务提供方连接,所以在使用的时候要注意缓存.
所以最好使用缓存

二、dubbo服务暴露和服务引入流程

这时候还可以进一步了解dubbo的服务暴露以及服务引入。

服务暴露

​​​

服务引入

三、泛化调用使用到的Filter

在发起泛化调用时,我们会将ReferenceConfig的属性generic设置为true。已标明这是一个泛化调用。

在泛化调用时,

调用方-->GenericImplFilter-->invoke【发起调用】-->GenericFilter-->服务方

仔细查看GenericImplFilter的逻辑                                                                                                        

GenericImplFilter实现了filter接口,Filter接口中定义了三个方法,invoke【具体调用】,onResponse【返回值处理】onError【异常情况处理】

其中invoke的代码为,大概意思就是invoke之前会做一个序列化的动作。需要注意的是如果是第一个if逻辑走进去,

会在RpcInvocation 里专门声明是一个generic_impl。

 

接着来看OnResponse,由上面可以得出,要是通过官网的泛化调用,是不会在invocation中塞入generic_impl。所以下面的逻辑完全不走,直接return泛化调用后服务端返回的结果。

四、 如何处理Dubbo泛化调用返回值

由第三部分得出,当使用dubbo官网推荐的泛化调用方式,服务端是不对返回值做任何处理的。但是既然我们想用他的返回值处理,就可以重写GenericImplFilter。

那首先禁用自带的Filter

dubbo:consumer:filter: -genericimpl

tips:怎么找每个Filter的名字

在以下目录下,因为Filter都是基于SPI机制【这块不了解的可以去百度】所以会在META-INF下配置

之后重写GenericImplFilter,只需要修改很简单的一段代码,把原来判断是否是GenericImpl的 逻辑修改,直接改为true,强行让返回值走序列化逻辑。

之前说了,debug的情况是序列化逻辑走

Type[] types = ReflectUtils.getReturnTypes(method);
appResponse.setValue(MyPojoUtils.realize(value, (Class<?>) types[0], types[1]));

也就是真正在做序列化动作的是PojoUtils.realize()。跟着看一下源码。真正起作用的是realize0()。逻辑就是将返回值每个都去解析,使用递归,解析到最小粒度【基本类型OR包装类型】如果是一个类,则会塞入一个key-value【"class":全类名】以此标明类。

这块递归如果不是能特别理解,可以自己debug一下

因为LocalDate,LocalTime,LocalDateTime不属于基本类型,在Java中认为他是一个包装类,所以会解析成一个HashMap。返回值如下。 

我们可以重写PojoUtils,因为返回的是一个hashmap,在如下代码加入我们自己序列化的逻辑。我这边用了一个模板模式

这块就不解析了,其实你用简单的if else 也可以达到相同的效果。

public class RpcSerializerHolder {private static final Map<Class, RpcSerializer> SERIALIZER_MAP = new ConcurrentHashMap<>();static {Collection<RpcSerializer> serializers = SpringUtil.getBeansOfType(RpcSerializer.class).values();for (RpcSerializer serializer : serializers) {SERIALIZER_MAP.put(serializer.canHandleClass(), serializer);}}public static RpcSerializer getByType(Class c){return SERIALIZER_MAP.get(c);}
}
public interface RpcSerializer<T> {// 将对象转换成你想要传输的格式Object serialize(Object object);// 返回处理的是什么类型Class canHandleClass();
}
@Component
public class LocalDateTimeSerializer implements RpcSerializer<LocalDateTime> {@Overridepublic Object serialize(Object object) {if (object instanceof Map<?, ?>) {Map<Object, Object> mapPojo = (Map<Object, Object>) object;Integer year = (Integer) mapPojo.get(SerializerConstant.YEAR);Integer month = (Integer) mapPojo.get(SerializerConstant.MONTH);Integer dayOfMonth = (Integer) mapPojo.get(SerializerConstant.DAY_OF_MONTH);Integer hour = (Integer) mapPojo.get(SerializerConstant.HOUR);Integer minute = (Integer) mapPojo.get(SerializerConstant.MINUTE);Integer second = (Integer) mapPojo.get(SerializerConstant.SECOND);LocalDateTime time = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second);long milliseconds = time.toInstant(ZoneOffset.of("+8")).toEpochMilli();return milliseconds;}return null;}@Overridepublic Class canHandleClass() {return LocalDateTime.class;}
}

Dubbo泛化调用处理序列化问题相关推荐

  1. 接口测试-dubbo泛化调用

    一.为什么要用dubbo泛化调用 泛化接口调用方式主要用于客户端没有 API 接口及模型类元的情况,参数及返回值中的所有 POJO 均用 Map 表示,通常用于框架集成,比如:实现一个通用的服务测试框 ...

  2. Dubbo 泛化调用

    dubbo 泛化调用 含义 使用 含义 官方说的文邹邹的,不太懂.按我的理解,就是可以通过指定某个接口的全限定名和方法名,调用远程有提供该方法的服务. 通过上篇文章Dubbo入门,我们可以知道作为服务 ...

  3. 代码技巧——dubbo泛化调用

    现在有一种业务场景: (1)业务方B调用任务系统A,提交一个任务,由A保证任务尽可能的被执行成功(系统A自带幂等.重试),在A完成任务的执行后将执行情况同步回调通知B应用: (2)因此,B应用在提交任 ...

  4. dubbo泛化调用原理

    泛接口调用方式主要用于客户端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Map表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过GenericService调用所有服 ...

  5. Dubbo笔记 ⑱ :泛化调用 泛化实现

    文章目录 一.前言 二.泛化调用与泛化实现 1. 泛化调用 2. 泛化实现 三.源码实现 1. GenericImplFilter 2. GenericFilter 四.总结 一.前言 本系列为个人D ...

  6. dubbo的调用原理及泛化调用

    简单介绍 dubbo是阿里开源出来的一个rpc框架,主要是用于微服务分布式项目的远程调用,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现,下面是调用的原理图: ...

  7. Dubbo泛化引用和泛化实现

    开篇 在Dubbo官方文档中关于泛化调用和泛化实现的说明,这里针对文档的案例做一些简单的说明和解释. 例子 // 引用远程服务 // 该实例很重量,里面封装了所有与注册中心及服务提供方连接,请缓存 R ...

  8. Apache Dubbo系列:泛化调用

    上一章,我们讲到了Dubbo的线程池策略,本章我们一起探讨,Dubbo如何实现泛化调用的.主要内容包括: 1.什么是泛化调用 2.泛化调用的三种方式 3.如何使用 4.源码分析 推荐阅读: Apach ...

  9. java impliments,dubbo使用GenericService泛化调用

    我们项目中常见场景,java应用内部接口都是使用dubbo,某个非java应用需要调用我们的接口的时候,无法使用dubbo,这是我们需要给它提供其他形式的接口,如restful api等等,这时我们需 ...

最新文章

  1. java chunked 解码_模拟http请求 带 chunked解析办法一
  2. 如何解决分布式系统中的“幽灵复现”?
  3. 他35岁,年薪100万,牛逼的人生无需解释
  4. bimmercode刷隐藏教程_PS教程:快速提取人物像素,制作人物海报主体,简单易学...
  5. 95-140-102-源码-transform-算子Map
  6. No module named sqlite3解决
  7. python入门指南小说-Python 入门指南
  8. stm32固件库文件
  9. 数据字典的主要作用是什么?
  10. Linux系统并搭建Sip server平台
  11. 解决网页打开慢/正在解析主机问题
  12. 京东云linux查看挂载磁盘,使用S3fs在Linux实例上挂载Bucket
  13. 计算机开机后无法网络拨号怎样处理,拨号上网时电脑假死的原因和解决方法
  14. Latex 绘制函数图像
  15. 基于Python的语音识别系统(孤立词)
  16. EDEM-fluent耦合时出现的问题及摸索出的解决办法及DPM颗粒信息导出
  17. Java电商系统秒杀怎么做?
  18. C++满足条件的数累加
  19. weboffice 6版本实现在线word
  20. 精准锁定证件材料篡改位置,合合信息智能图像处理技术助力金融机构防范违规开户

热门文章

  1. 物联网典型场景之智能家电,使用JOSH技术带来的优势和机会
  2. 源代码 Source Code
  3. UC/OS-II 源码下载【资源】
  4. Games101--现代计算机图形学入门 作业3笔记(渲染管线、着色模型、双线性插值)
  5. CG100一汽威志防盗
  6. 每天五分钟机器学习:超平面分离定理和凸优化
  7. a 便签实现 下载
  8. JAVA计算机毕业设计成都某4S店销售管理系统Mybatis+系统+数据库+调试部署
  9. matlab实习,matlab上实习指导书.doc
  10. orcale 查询重复项