java序列化和反序列化

2021-01-17 22:16

阅读:463

绕开transient机制的办法

虽然name被transient修饰,但是通过我们写的这两个方法依然能够使得name字段正确被序列化和反序列化
writeObject和readObject原理
writeObject和readObject是两个私有的方法,他们是什么时候被调用的呢?从运行结果来看,它确实被调用。而且他们并不存在于Java.lang.Object,也没有在Serializable中去声明。我们唯一的猜想应该还是和ObjectInputStream和ObjectOutputStream有关系,所以基于这个入口去看看在哪个地方有调用

技术图片

 

 

 从源码层面来分析可以看到,readObject是通过反射来调用的。其实我们可以在很多地方看到readObject和writeObject的使用,比如HashMap。

 

Java序列化的一些简单总结
1.Java序列化只是针对对象的状态进行保存,至于对象中的方法,序列化不关心
2.当一个父类实现了序列化,那么子类会自动实现序列化,不需要显示实现序列化接口
3.当一个对象的实例变量引用了其他对象,序列化这个对象的时候会自动把引用的对象也进行序列化(实现深度克隆)
4.当某个字段被申明为transient后,默认的序列化机制会忽略这个字段5.被申明为transient的字段,如果需要序列化,可以添加两个私有方法:writeObject和readObject

 

分布式架构下常见序列化技术

 

初步了解了Java序列化的知识以后,我们又得回到分布式架构中,了解序列化的发展过程

了解序列化的发展

随着分布式架构、微服务架构的普及。服务与服务之间的通信成了最基本的需求。这个时候,我们不仅需要考虑通信的性能,也需要考虑到语言多元化问题所以,对于序列化来说,如何去提升序列化性能以及解决跨语言问题,就成了一个重点考虑的问题。
由于Java本身提供的序列化机制存在两个问题

 

1.序列化的数据比较大,传输效率低
2.其他语言无法识别和对接以至于在后来的很长一段时间,基于XML格式编码的对象序列化机制成为了主流,一方面解决了多语言兼容问题,另一方面比二进制的序列化方式更容易理解。以至于基于XML的SOAP协议及对应的WebService框架在很长一段时间内成为各个主流开发语言的必备的技术。再到后来,基于JSON的简单文本格式编码的HTTP REST接口又基本上取代了复杂的Web Service接口,成为分布式架构中远程通信的首要选择。但是JSON序列化存储占用的空间大、性能低等问题,同时移动客户端应用需要更高效的传输数据来提升用户体验。在这种情况下与语言无关并且高效的二进制编码协议就成为了大家追求的热点技术之一。首先诞生的一个开源的二进制序列化框架-MessagePack。它比google的Protocol Buffers出现得还要早。

 

简单了解各种序列化技术

 XML序列化框架介绍

XML序列化的好处在于可读性好,方便阅读和调试。但是序列化以后的字节码文件比较大,而且效率不高,适用于对性能不高,而且QPS较低的企业级内部系统之间的数据交换的场景,同时XML又具有语言无关性,所以还可以用于异构系统之间的数据交换和协议。比如我们熟知的Webservice,就是采用XML格式对数据进行序列化的。XML序列化/反序列化的实现方式有很多,熟知的方式有XStream和Java自带的XML序列化和反序列化两种

 

JSON序列化框架
JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,相对于XML来说,JSON的字节流更小,而且可读性也非常好。现在JSON数据格式在企业运用是最普遍的JSON序列化常用的开源工具有很多
1.Jackson (https://github.com/FasterXML/jackson)
2.阿里开源的FastJson(https://github.com/alibaba/fastjson)
3.Google的GSON( https://github.com/google/gson )这几种json序列化工具中,Jackson与fastjson要比GSON的性能要好,但是Jackson、GSON的稳定性要比Fastjson好。而fastjson的优势在于提供的api非常容易使用

 

Hessian序列化框架
Hessian是一个支持跨语言传输的二进制序列化协议,相对于Java默认的序列化机制来说,Hessian具有更好的性能和易用性,而且支持多种不同的语言
实际上Dubbo采用的就是Hessian序列化来实现,只不过Dubbo对Hessian进行了重构,性能更高

 

Avro序列化
Avro是一个数据序列化系统,设计用于支持大批量数据交换的应用。它的主要特点有:支持二进制序列化方式,可以便捷,快速地处理大量数据;动态语言友好,Avro提供的机制使动态语言可以方便地处理Avro数据。

 

序列化技术的选型

技术层面
1.序列化空间开销,也就是序列化产生的结果大小,这个影响到传输的性能
2.序列化过程中消耗的时长,序列化消耗时间过长影响到业务的响应时间
3.序列化协议是否支持跨平台,跨语言。因为现在的架构更加灵活,如果存在异构系统通信需求,那么这个是必须要考虑的
4.可扩展性/兼容性,在实际业务开发中,系统往往需要随着需求的快速迭代来实现快速更新,这就要求我们采用的序列化协议基于良好的可扩展性/兼容性,比如在现有的序列化数据结构中新增一个业务字段,不会影响到现有的服务
5.技术的流行程度,越流行的技术意味着使用的公司多,那么很多坑都已经淌过并且得到了
解决,技术解决方案也相对成熟
6.学习难度和易用性

 

选型建议
1.对性能要求不高的场景,可以采用基于XML的SOAP协议
2.对性能和间接性有比较高要求的场景,那么Hessian、Protobuf、Thrift、Avro都可以。
3.基于前后端分离,或者独立的对外的api服务,选用JSON是比较好的,对于调试、可读性都很不错
4.Avro设计理念偏于动态类型语言,那么这类的场景使用Avro是可以的

各个序列化技术的性能比较

这个地址有针对不同序列化技术进行性能比较:https://github.com/eishay/jvm-serializers/wiki

 


评论


亲,登录后才可以留言!