序列化实现方式简介
序列化:将对象的状态信息转换为可存储或传输形式的过程,简言之,就是把对象转换为字节序列的过程就是对象的序列化
反序列化的过程:序列化的逆过程,将字节数组反序列化回复为对象的过程就是对象的反序列化
使用序列化能够帮助我们解决如下几个问题
- 通过将对象序列化为字节数组,使得不共享内存网络的能够进行对象的传输
- 能够将对象永久存储到存储设备
- 解决了远程接口调用JVM之间内存无法共享的问题
评价一个序列化算法的优劣的两个指标
- 序列化码流的大小
- 序列化本身的速度和系统资源的开销(包括内存,CPU等)
JDK自带的序列化
Java的序列化主要通过对象输出流ObjectOutputStream,对象输入流ObjectInputStream来实现,其中被序列化的类需要实现Serializable接口
- 序列化的时候只能保存对象的状态,不保存对象的方法
- 当一个父类序列化的时候,子类自动实现序列化,不需要显示的实现Serializable接口
- 当一个对象的实例变量用用其他兑现过得时候,序列化该对象也把引用对象进行序列化
- 当某个字段被声明为transient之后,默认的序列化机制就会忽略这个字段
- 对于当属一倍声明为transietn的字段,可以在类中添加私有方法writeObject()和readObject()两个方法来进行序列化
Jdk自带的序列化方式有着明显的优缺点,一方面他是java语言自带的,就没有必要去引入第三方依赖了,另一方面其只支持Java语言,不支持跨语言,而且性能较差,序列化后产生的码流过大,对于引用过深的对象序列化易发生内存OOM异常
XML序列化
使用XML序列化具有可读性好,利于调试的优势,但是因为使用标签来表示数据,所以导致序列化之后码流很大,而且效率也不高,比较适用于对性能要求不高,QPS较低的企业内部系统之间的数据交换场景,而且XML与语言无关,比较使用与异构系统之间的数据交换协议
使用fastJson实现序列化
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,比XML码流小,而且保留了XML可读性比较好的优势。
Hessian序列化框架
Hessian是一个支持跨语言传输的二进制序列化协议,相对于Java默认的序列化方式,其具有更好的性能与易用性,而且支持不同的语言
protostuff序列化
说protostuff之前先说说protobuf
protobuf是Google提供的一种数据交换的格式,独立于平台,独立于语言,protobuf是一个纯粹的展示层协议,可以和各种传输协议一起使用。
protobuf具有非常广泛的用户基础,空间开销小,而且具有很高的解析性能,非常实用对性能要求高的公司进行RPC调用,序列化后的数据量相对较少,也适合应用层对象的持久化场景
但是使用protobuf需要编写protocol.IDL文件,使用起来工作量很大。
protostuff基于protobuf,protostuff-runtime实现了无需预编译JavaBean进序列化序列化的能力
序列化框架的选型
每一种序列化协议都已各自的优缺点和应用场景。在选择序列化方式的时候,我们应该从以下几点考虑
- 序列化的空间开销,即码流大小,码流过大会对带宽以及存储空间造成较大的压力
- 序列化的时间开销,序列化耗时过长会拖慢整个服务的响应时间
- 序列化协议是否支持跨平台,跨语言。
- 可扩展性和兼容性
选型建议:
- 对于公司之间的系统调用,性能要求在100ms以上的服务,推荐基于XML方式
- 基于WebBrowser的Ajax,以及Mobile APP与服务端之间的通信,JSON协议首选,对于性能要求不高,或者以动态类型的语言为主,或者传输数据载荷很小的厄运用场景,JSON是一个非常不错的选择
- 对性能和简洁性要求较高 Hessian protobuf
- 对序列化之后需要支持不同的传输层协议,或者需要跨防火墙访问的高性能场景以及T级别的数据持久化的应用场景Protobuf