资讯专栏INFORMATION COLUMN

了解dubbo序列化 从bug开始

lemanli / 3400人阅读

摘要:就是默认的序列化器和反序列化器。最后,那为什么会到这一步呢发现拿到反序列化器后会执行一个操作基本上就到这里了,最主要的原因还是方法,并不是很多博文说的。

    首先交代背景,前几天遇到一个小bug,由于其他系统的一个DTO子类和父类有一个字段名重复了,所以导致我set的子类字段那边拿不到值。改起来很简单嘛,让对面把子类的字段删掉就好,但是拿不到值的原因让我想了很久,很明显是序列化和反序列化的过程中这个字段的值丢失了,但是到底是在哪一步呢?还是决定看看源码给自己一个答案。

dubbo版本:2.6.7

首先先确定协议和序列化的方式:

ok,dubbo协议,没有配序列化方式,那再来找一下dubbo默认的序列化方式:
首先找到了这个包:

然后在Serialization接口(实现一些自定义序列化扩展用的)中发现了默认序列化的方式是hessian2

然后通过Hessian2Serializationserialize方法和deserialize方法找到了Hessian2ObjectOutputHessian2ObjectInput这个两个类,之后通过里面的writeObject方法和readObject方法,找到了这两个类:JavaSerializerJavaDeserializer。就是默认的序列化器和反序列化器。

首先我们来看序列化:
构造方法:

我们看看他干了个什么事
首先检查了有没有writeReplace方法
然后把所有声明的字段放到数组中遍历,然后把除了transientstatic修饰的字段放到ArrayList中去
然后往上找父类执行相同操作
然后把所有符合条件的字段放到一个Field数组里面,先放基本数据类型,再放引用数据类型
最后把字段放入对应类型的序列化器中去
得到一个FieldSerializer序列化器数组

我们还是继续看writeObject方法

主要是第二张图的3个方法,做的事情大概就是循环序列化field的名和值

下面再来看看反序列化:
构造方法:

这里大概做了3个事
获取fieldMap,方法如下:

获取readResolve方法
获取所有构造器
遍历构造器数组找到cost最小的最佳构造器
然后用最佳构造器进行构造,方法如下:

先看构造器方法,基本数据类型的话返回包装类型,引用数据类型返回null

主要我们来看获取fieldMap的时候。和序列化时相同,先取子类再取父类,本来以为到这就结束了,可是看到了一行校验

fieldMap.get(field.getName()) == null

如果父类的字段名和子类字段名相同,会跳过该循环,也就是说只会有子类的值,那为什么还会覆盖?
看最后一个readMap方法:

debug发现值被覆盖就是在这里操作的

deser.deserialize(in, obj);

子类set过值以后,父类过来也会拿到子类的反序列化器,把子类的值覆盖掉。

最后,那为什么会到readMap这一步呢?

debug发现SerializerFactory拿到反序列化器后会执行一个readMap操作

基本上就到这里了,最主要的原因还是readMap方法,并不是很多博文说的fieldMap。如果哪里有不对的地方欢迎指出、讨论以便及时修改。

参考文档:链接描述

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76565.html

相关文章

  • dubbo 2.5.3对于java.sql的反列化BUG

    摘要:使用的序列化是的,而对于类的反序列化的源码如下这里我们可以清楚地看出来,将读取到的转为然后调用了方法,那么如果我们的属性为空,那么调用函数必然会抛异常,也就产生了之后的结果。补充说明我找到的源码可以看出,对于,,的反序列化均有问题存在。 背景 这是我之前提的问题:问题链接 在使用dubbo 2.5.3的时候,定义的接口中有一个方法使用了实体类作为参数,而这个实体类中定义了一个变量为ja...

    刘玉平 评论0 收藏0
  • dubbo源码解析(四十三)2.7新特性

    摘要:大揭秘目标了解的新特性,以及版本升级的引导。四元数据改造我们知道以前的版本只有注册中心,注册中心的有数十个的键值对,包含了一个服务所有的元数据。 DUBBO——2.7大揭秘 目标:了解2.7的新特性,以及版本升级的引导。 前言 我们知道Dubbo在2011年开源,停止更新了一段时间。在2017 年 9 月 7 日,Dubbo 悄悄的在 GitHub 发布了 2.5.4 版本。随后,版本...

    qqlcbb 评论0 收藏0
  • dubbo个人理解于应用章(二)

    摘要:当提供程序线程池耗尽时,不能发送到使用者端。一些错误修正动态配置不能删除,支持参数,监控统计问题等新功能支持手册线程池耗尽时自动堆栈转储。在注册表无法连接时被阻止。正常关机,在注册表取消注册和线程池关闭之间增加额外的等待时间。 dubbo分析showImg(https://segmentfault.com/img/bVbam2f?w=1726&h=686); dubbo为什么要对接sp...

    AlphaWallet 评论0 收藏0
  • 一个JAVA开发一年的总结

    摘要:前言到今天为止,正好是工作一年了。一年里有过折磨痛苦,有过成就感,一年后很欣慰能看到自己是有所收获的。自己做出了一件很棒的事情完全可以拿去和别人炫耀,比如你用了一个很好的设计模式,比如你优化了一个功能让他快了倍,比如你开发了一个很棒的工具。 前言 到今天为止,正好是工作一年了。一年里有过折磨痛苦,有过成就感,一年后很欣慰能看到自己是有所收获的。记录如下,如有不当,还望指点。 技术 看...

    Reducto 评论0 收藏0
  • dubbo源码解析(一)Hello,Dubbo

    摘要:英文全名为,也叫远程过程调用,其实就是一个计算机通信协议,它是一种通过网络从远程计算机程序上请求服务而不需要了解底层网络技术的协议。 Hello,Dubbo 你好,dubbo,初次见面,我想和你交个朋友。 Dubbo你到底是什么? 先给出一套官方的说法:Apache Dubbo是一款高性能、轻量级基于Java的RPC开源框架。 那么什么是RPC? 文档地址:http://dubbo.a...

    evin2016 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<