序列化方式常见的有5种,包含:Java序列化、Hessian、Json等序列化方式,下面我一一来详解@mikechen
本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》里面。
1.Java原生序列化
Java类通过实现Serializable接口来实现该类对象的序列化,如下代码示例:
public class TestBean implements Serializable {
private Integer id;
private String name;
private Date date;
//省去getter和setter方法和toString
}
这个接口非常特殊,没有任何方法,只起标识作用,Java序列化保留了对象类的元数据(如类、成员变量、继承类信息等),以及对象数据等,兼容性最好,但不支持跨语言,而且性能一般。
实现Serializable接口的类建议设置serialVersionUID字段值,如果不设置,那么每次运行时,编译器会根据类的内部实现,包括类名、接口名、方法和属性等来自动生成serialVersionUID。
如果类的源代码有修改,那么重新编译后serial VersionUID的取值可能会发生变化。
因此实现Serializable接口的类一定要显式地定义serialVersionUID属性值。
import java.io.Serializable;
public class Person implements Serializable{
private static final long serialVersionUID = 1234567890L;
private int id;
private String name;
public Person(int id, String name){
this.id = id;
this.name = name;
}
public String toString(){
return "Person: " + id + " " + name;
}
}
2.Hessian 序列化
Hessian 序列化是一种支持动态类型、跨语言、基于对象传输的网络协议。
Hessian 序列化特性:
- 自描述序列化类型,不依赖外部描述文件或者接口定义,用一个字节表示常用的基础类型,极大缩短二进制流;
- 语言无关,支持脚本语言;
- 协议简单,比Java原生序列化高效;
- 相比hessian1,hessian2中增加了压缩编码,其序列化二进制流大小是Java序列化的50%,序列化耗时是Java序列化的30%,反序列化耗时是Java序列化的20%。
在使用Hessian序列化之前,需要在maven工程中,引入Hessian依赖:
com.caucho
hessian
4.0.62
无论jdk序列化,还是hessian序列化,实体类均需要实现Serializable接口。
具体代码示例:
public class Test {
public static void main(String[] args) throws Exception {
ByteArrayOutputStream os = new ByteArrayOutputStream();
Hessian2Output output = new Hessian2Output(os);
output.writeObject(Person.hehe(123L, "wangyong"));
output.close();
ByteArrayInputStream in = new ByteArrayInputStream(os.toByteArray());
Hessian2Input input = new Hessian2Input(in);
System.out.println(input.readObject());
}
}
class Person implements Serializable {
private Long id;
private String name;
private Person(long id, String name) {
this.id = id;
this.name = name;
System.out.println("call dd");
}
public static Person hehe(Long id, String name) {
Person p = new Person(id, name);
return p;
}
@Override
public String toString() {
return "id=" + id + ", name=" + name;
}
}
更多参考官方:
http://hessian.caucho.com/doc/hessian-serialization.html
3.Json序列化
关于Json 可以说是web 开发不管是前端还是后端都是非常的熟悉,JSON是一种轻量级的数据交换格式。
JSON 序列化就是将数据对象转换为 JSON 字符串,在序列化过程中抛弃了类型信息,相比前两种方式,JSON 可读性比较好,方便调试。
Json语法规则:
- 数据在键值对中
- 数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
具体示例如下:
{
"employees": [
{ "firstName":"Mike" , "lastName":"Chen" },
{ "firstName":"Anna" , "lastName":"Smith" },
{ "firstName":"Peter" , "lastName":"Jones" }
]
}
4.ProtoBuf
谷歌推出的,是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于通信协议、数据存储等。
Protobuf应用场景
序列化后体积小,一般用于对传输性能有较高要求的系统,Protobuf序列化方式适用于跨语言通信、对码流大小和性能要求高、且pojo不经常变化的场景。
Protobuf使用
要想使用Protobuf就需要先定义proto文件,先熟悉protobuf消息定义的相关语法。
定义消息类型,示例如下:
syntax = "proto3";
message SendRequest {
string query = 1;
int32 page_number = 2;
repeated int32 result_per_page = 3;
}
- .proto文件的第一行指定了使用proto3语法,说明使用的是proto3版本,如果省略protocol buffer编译器就默认使用proto2语法;
- message表示消息类型,可以有多个;
- SendRequest定义中指定了三个字段(name/value键值对),每个字段都会有名称和类型;
- repeated是字段规则。
5.Kryo
Kryo 是一个 Java 序列化框架,号称 Java 最快的序列化框架,Kryo 在序列化速度上很有优势,底层依赖于字节码生成机制。
Kryo 的特点:
- 序列化的性能非常高
- 序列化结果体积较小
- 提供了简单易用的API
但是由于只能限定在 JVM 语言上,所以 Kryo 不支持跨语言使用。
Kryo序列化被很多开源项目使用,社区非常活跃:
- Apache Hive
- Apache Spark
- Twitter's Chill
- Storm
- akka-kryo-serialization
Kryo序列化具体示例如下:
static void quickStart() throws FileNotFoundException {
Kryo kryo = new Kryo();
Output output = new Output(new FileOutputStream("file.bin"));
SomeClass someObject = new SomeClass();
someObject.setValue("this is someObject.");
kryo.writeObject(output, someObject);
output.close();
Input input = new Input(new FileInputStream("file.bin"));
SomeClass deSomeObject = kryo.readObject(input, SomeClass.class);
input.close();
Assert.assertEquals(someObject.getValue(), deSomeObject.getValue());
}
序列化方式小结
本文主要对几种常见序列化方式:Java原生序列化、Hessian、Json、Protobuff、Kryo等序列化进行详解,希望对你掌握序列化有所帮助。
本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》里面。
本文暂时没有评论,来添加一个吧(●'◡'●)