除开前面提到的几种序列化方案外,相信看过Dubbo框架源码的小伙伴,一定还知道一种方案,即基于二进制实现Hessian,这是Dubbo中默认的序列化机制,用于服务提供者与消费者之间进行数据传输,这里咱们也简单过一下。
Hessian和JDK原生的序列化技术,兼容度很高,相较于使用ProtoBuf而言,成本要低许多,首先导入一下依赖包:
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.65</version>
</dependency>
接着依旧基于最开始的ZhuZi实体类,来写一下测试代码:
public classHessianDemo{
publicstaticvoidmain(String[] args)throwsException{
// 1. 序列化
ZhuZizhuZi=newZhuZi(1,"黄金竹子","A级");
byte[] serializeBytes = serialize(zhuZi);
System.out.println("Hessian序列化后字节数组长度:"+ serializeBytes.length);
// 2. 反序列化
ZhuZideserializeZhuZi= deserialize(serializeBytes);
System.out.println(deserializeZhuZi.toString());
}
/**
* 序列化方法
* @param zhuZi 需要序列化的对象
* @return 序列化后生成的字节流
*/
privatestaticbyte[] serialize(ZhuZi zhuZi)throwsIOException{
ByteArrayOutputStreambos=newByteArrayOutputStream();
Hessian2Outputh2o=newHessian2Output(bos);
h2o.writeObject(zhuZi);
h2o.close();
return bos.toByteArray();
}
/**
* 反序列化方法
* @param bytes 字节序列(字节流)
* @return 实体类对象
*/
privatestaticZhuZideserialize(byte[] bytes)throwsException{
ByteArrayInputStreambis=newByteArrayInputStream(bytes);
Hessian2Inputh2i=newHessian2Input(bis);
ZhuZizhuZi=(ZhuZi) h2i.readObject();
h2i.close();
return zhuZi;
}
}
上述代码对比最开始的JDK序列化方案,几乎一模一样,只是将输出/输入流对象,从ObjectOutputStream、ObjectInputStream换成了Hessian2Output、Hessian2Input,此时来看结果对比,如下:
JDK序列化后的字节数组长度:224
ZhuZi(id=1, name=黄金竹子, grade=A级)
=============================================
Hessian序列化后字节数组长度:70
ZhuZi(id=1, name=黄金竹子, grade=A级)
是不是特别惊讶?
其余任何地方没有改变,仅用Hessian2替换掉JDK原生的IO流对象,结果码流体积竟然缩小了3.2倍!
并且还完全保留了JDK序列化技术的特性,还支持多语言异构……,所以,这也是Dubbo使用Hessian2作为默认序列化技术的原因,不过Dubbo使用的是定制版,依赖如下:
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-hessian2</artifactId>
<version>3.2.0-beta.6</version>
</dependency>
感兴趣的可以去看看DecodeableRpcInvocation#decode()、encode()这个两个方法,其中涉及到数据的编解码工作,默认采用Hessian2序列化技术~
标签:ZhuZi,java,字节,JDK,zhuZi,序列化,Hessian From: https://www.cnblogs.com/o-O-oO/p/18394914