文章来源:https://dwz.cn/We2yALQE

作者: idea

序列化通信

将对象转换为字节数组,方便在网络中进行对象的传输。在网络通信中,不同的计算机进行相互通信主要的方式就是将数据流从一台机器传输给另外一台计算机,常见的传输协议包括了TCP,UDP,HTTP等,网络io的方式主要包括有了aio,bio,nio三种方式。

当客户端将需要请求的数据封装好了之后就需要进行转换为二进制格式再转换为流进行传输,当服务端接收到流之后再将数据解析为二进制格式的内容,再按照约定好的协议进行处理解析。最常见的场景就是rpc远程调用的时候,对发送数据和接收数据时候的处理。

下边我们来一一介绍一下现在比较常见的几款序列化技术框架。

jdk序列化

jdk自身便带有序列化的功能,Java序列化API允许我们将一个对象转换为流,并通过网络发送,或将其存入文件或数据库以便未来使用,反序列化则是将对象流转换为实际程序中使用的Java对象的过程。

先来看看实际的代码案例

首先我们创建一个基础的测试Person类

如果某些特殊字段不希望被序列化该如何处理?

这里面如果有相应的属性不希望被序列化操作的话,可以使用transient关键字进行修饰,例如希望tel属性不希望被序列化,可以改成这样:

 private transient String tel;

这样的话,该对象在反序列化出来结果之后,相应的属性就会为null值。

为什么要定义serialVersionUID?

序列化操作时,系统会把当前类声明的serialVersionUID写入到序列化文件中,用于反序列化时系统会去检测文件中的serialVersionUID,判断它是否与当前类的serialVersionUID一致,如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。

如果没有定义serialVersionUID时

当实现当前类没有显式地定义一个serialVersionUID变量时候,Java序列化机制会根据编译的Class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,如果类信息进行修改,会导致反序列化时serialVersionUID与原先值无法match,反序列化失败。

通过jdk提升的序列化对其进行相应的序列化和反序列化的代码案例

jdk序列化的缺点

1、无法跨语言

这一缺点几乎是致命伤害,对于跨进程的服务调用,通常都需要考虑到不同语言的相互调用时候的兼容性,而这一点对于jdk序列化操作来说却无法做到。这是因为jdk序列化操作时是使用了java语言内部的私有协议,在对其他语言进行反序列化的时候会有严重的阻碍。

2、序列化之后的码流过大

jdk进行序列化编码之后产生的字节数组过大,占用的存储内存空间也较高,这就导致了相应的流在网络传输的时候带宽占用较高,性能相比较为低下的情况。

Hessian序列化框架

Hessian是一款支持多种语言进行序列化操作的框架技术,同时在进行序列化之后产生的码流也较小,处理数据的性能方面远超于java内置的jdk序列化方式。

相关的代码案例:

Hessian的源码里面,核心主要还是com.caucho.hessian.io里面的代码,AbstractSerializer是Hessian里面的核心序列化类,当我们仔细查看源码的时候就会发现hessian提供了许多种序列化和反序列化的类进行不同类型数据的处理。(我使用的是hessian4.0,因此相应的类会多很多)

在SerializerFactory里面有getSerializer和getDefaultSerializer的函数,专门用于提取这些序列化和反序列化的工具类,这样可以避免在使用该工具类的时候又要重新实例化,这些工具类都会被存储到不同的ConcurrentHashMap里面去。

ps:对于hessian3.0时候的Serializer/Derializer实现功能没有考虑到对于异常信息进行序列化处理,因此如果遇到相应问题的朋友可以考虑将hessian的版本提升到3.1.5以上。

Kryo序列化技术

Kryo是一种非常成熟的序列化实现,已经在Twitter、Groupon、 Yahoo以及多个著名开源项目(如Hive、Storm)中广泛的使用,它的性能在各个方面都比hessian2要优秀些,因此dubbo后期也开始渐渐引入了使用Kryo进行序列化的方式。

对于kryo的使用,我们来看看相应代码:

首先我们引入相应的依赖:

 com.esotericsoftware kryo-shaded 3.0.3

然后就是基础的序列化和反序列化代码操作了

ps:这里我们需要注意,Kryo不支持没有无参构造函数的对象进行反序列化,因此如果某个对象希望使用Kryo来进行序列化操作的话,需要有相应的无参构造函数才可以。

由于Kryo不是线程安全,因此当我们希望使用Kryo构建的工具类时候,需要在实例化的时候注意线程安全的问题。代码案例:

XStream实现对象的序列化

在使用XStream进行序列化技术的实现过程中,类中的字符串组成了 XML 中的元素内容,而且该对象还不需要实现 Serializable 接口。XStream不关心被序列化/反序列化的类字段的可见性,该对象也不需要有getter/setter方法和默认的构造函数。

引入的依赖:

com.thoughtworks.xstream xstream 1.4.9

通过使用XStream来对对象进行序列化和反序列化操作:

google的Protobuf

google protobuf是一个灵活的、高效的用于序列化数据的协议。相比较XML和JSON格式,protobuf更小、更快、更便捷。google protobuf是跨语言的,并且自带了一个编译器(protoc),只需要用它进行编译,可以编译成Java、python、C++、C#、Go等代码,然后就可以直接使用,不需要再写其他代码,自带有解析的代码。

protobuf相对于kryo来说具有更加高效的性能和灵活性,能够在实际使用中,当对象序列化之后新增了字段,在反序列化出来的时候依旧可以正常使用。(这一点kryo无法支持)

不同序列化框架的总结

目前已有的序列化框架还有很多在文中没有提到,日后假若在开发中遇到的时候可以适当的进行归纳总结,比对各种不同的序列化框架之间的特点。

dubbo kryo序列化_Java后端精选技术:序列化框架的选型和比对相关推荐

  1. java后端技术有哪些_Java后端精选技术:什么是JVM?

    说明:做java开发的几乎都知道jvm这个名词,但是由于jvm对实际的简单开发的来说关联的还是不多,一般工作个一两年(当然不包括爱学习的及专门做性能优化的什么的),很少有人能很好的去学习及理解什么是j ...

  2. dao接口有什么好处_Java后端精选技术:我们为什么要使用AOP?

    前言 之前写了一篇文章Spring3:AOP,是当时学习如何使用Spring AOP的时候写的,比较基础.这篇文章最后的推荐以及回复认为我写的对大家有帮助的评论有很多,但是现在从我个人的角度来看,这篇 ...

  3. java后端技术路线_Java后端精选技术:Java的反射机制

    反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. ...

  4. 前后端分离技术——前端框架

    本文主要介绍前后端分离技术--前端框架. 一.前端框架 前端框架均为近年新兴技术,包括:业务相关.环境相关等方面.从组件化.可视化.信息化.扁平化.数据驱动等多角度设计架构.以用户体验为原则,综合业务 ...

  5. java高性能序列化_Java最佳实践–高性能序列化

    java高性能序列化 在使用Java编程语言时,我们将继续讨论与建议的实践有关的系列文章,我们将讨论并演示如何将对象序列化用于高性能应用程序. 所有讨论的主题均基于用例,这些用例源于电信行业关键任务超 ...

  6. java 为什么序列化_java类为什么要序列化

    将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象. 序列化使其他代码可以查看或 ...

  7. java get方法不序列化_Java中的Json序列化,不容忽视的getter

    在开发的过程中,经常会碰到和自己预期不一样的情况.有的时候自己去研究一下还是很有趣的.这两天在写java web的时候,碰到了一个对象序列化的问题. 问题重现 public class AjaxJso ...

  8. double类型最大值_Java后端精选基础教程:Java 中的基本数据类型「连载 6」

    数据类型定义了变量可以采用的值,例如,定义变量为 int 类型,则只能取整数值. 在 Java 中有两类数据类型: 1)原始数据类型 2)非原始数据类型 - 数组和字符串是非原始数据类型,将在以后的教 ...

  9. beaninfo详解源码解析 java_Java后端精选技术:源码解析Spring Cloud Zuul

    Zuul 架构图 在zuul中, 整个请求的过程是这样的,首先将请求给zuulservlet处理,zuulservlet中有一个zuulRunner对象,该对象中初始化了RequestContext: ...

  10. java实体序列化_java – 在JPA实体序列化(JSON)上防止JAX-RS中...

    我有一个实体如下: @XmlRootElement @Entity @Table(name="CATEGORY") @Access(AccessType.FIELD) @Cache ...

最新文章

  1. mysql 如何修改wait_timeout,interactive_timeout ,和 session ,global 有什么关系
  2. G6 图可视化引擎——简介
  3. web工程导入MyEclipse 就变成Java工程 ———— 解决方案
  4. matlab常用函数——数学函数
  5. eureka 其它语言_SpringCloud之Eureka-Go语言中文社区
  6. java隐藏与覆盖_java中方法的隐藏和覆盖问题?
  7. C语言验证6174数学问题
  8. 【网络编程】time_wait状态产生的原因,危害,如何避免
  9. opengl es3.0游戏开发学习笔记2--绘制地月星系
  10. 联盛德 HLK-W806 (十三): 运行FatFs读写FAT和exFat格式的SD卡/TF卡
  11. 鸟与虫(四)pexels搜到的我都想要,
  12. 42个5G智慧教育应用场景,告诉你5G将如何改变教育
  13. 如何让计算机显示器满屏,电脑显示器满屏条纹的解决方法
  14. 网络安全面试、实习、校招经验打包分享
  15. 不同excel根据某列相同字段值进行关联
  16. window系统安装msysgit(Git客户端软件)教程
  17. 杨绛十句话,最好背下来
  18. 数据结构(从概念到C++实现)
  19. javascript将table的td变为可编辑的input,实现表格动态编辑(带示例版)
  20. 计算机音乐技术的发展,计算机网络技术对音乐发展的影响探析

热门文章

  1. UVA11082 行列模型
  2. jsp中target=_blank的用法
  3. Java基础知识强化之IO流笔记19:FileOutputStream的三个write方法
  4. Arch Linux freemind中文乱码
  5. HTML与JSP页面的区别
  6. ios 通知接收两次_苹果健康体系又进一步,iOS 14.3支持有氧适能通知
  7. 《完整部署 OCS-NG》
  8. 树的遍历 (和) 玩转二叉树 的总结博客
  9. css的写法 有点凌乱(养成这习惯 神马浏览器兼容都是浮云 so easy)
  10. ActiveMQ笔记(二)