日拱一卒系列(protobuf入门)
1.引子
上一次我们在聊一聊jdk序列化中,分享了在实际应用场景中如何选择编解码框架,我们说需要考虑这么几个点
跨语言,因为需要在不同编程语言实现的系统之间通信传递消息
编码码流要小,因为需要节省带宽,节省存储资源
编解码性能要好,因为需要应对高并发、高负载
并且上一次我们说,不推荐使用jdk 的序列化,原因是jdk的序列化是java的私有协议,不能跨语言,且编码码流较大,且编解码性能慢(当时我们把jdk的序列化,与通用二进制做了对比)。
基于此,那么你可能会问了,在实际项目中,通常都会选择什么样的编解码框架呢?今天我们就来聊一聊Google提供的protobuf编解码框架,通过这篇文章,我期望分享给你
什么是protobuf
如何使用protobuf
2.案例
2.1.什么是protobuf
protobuf全名称是 Protocol Bufferes,它是由Google开源的序列化框架(编解码框架)。打开它的官网( https://developers.google.cn/protocol-buffers/ ),我们可以看到它有以下特点
语言无关、平台无关、支持多语言(c++/c#/go/java/python)
通用二进制编解码,编码码流小
通用二进制编解码,编解码性能好
从官网的介绍,这不就是我们在实际应用中,选择编解码框架的最佳标准吗?更重要的一点是,protobuf使用起来非常简单,易用性好!只需要
导入protobuf依赖
编写.proto文件
下载protobuf 编译器,将.proto文件,编译成目标语言源代码
2.2.protobuf入门案例
2.2.1.导入依赖
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.9.1</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.9.1</version>
</dependency>
2.2.2.编写Person.proto文件
syntax = "proto2";
package com.anan.netty.protobuf;
option optimize_for = SPEED;
option java_package = "com.anan.netty.protobuf";
option java_outer_classname = "DataInfo";
message Person {
required string name = 1;
optional int32 age =2;
optional string address = 3;
}
2.2.3.下载protobuf编译器
2.2.4.通过编译器编译代码
protoc -I=./proto --java_out=./src ./proto/Person.proto
2.2.5.应用
public static void main(String[] args) throws Exception{
// 1.序列化
DataInfo.Person person = DataInfo.Person.newBuilder()
.setName("小明")
.setAge(18)
.setAddress("广东省广州市天河区")
.build();
byte[] personBytes = person.toByteArray();
System.out.println("【person】原生对象,姓名:" + person.getName()
+ ",年龄:" + person.getAge()
+ ",地址:" + person.getAddress());
System.out.println("【personBytes】字节数组:" + personBytes);
// 2.反序列化
System.out.println("------------------华丽丽分割线------------------");
DataInfo.Person parsePersonFrom = DataInfo.Person.parseFrom(personBytes);
System.out.println("【personBytes】反序列化回对象,姓名:" + parsePersonFrom.getName()
+ ",年龄:" + parsePersonFrom.getAge()
+ ",地址:" + parsePersonFrom.getAddress());
}
【person】原生对象,姓名:小明,年龄:18,地址:广东省广州市天河区
【personBytes】字节数组:[B@506e1b77
------------------华丽丽分割线------------------
【personBytes】反序列化回对象,姓名:小明,年龄:18,地址:广东省广州市天河区
Process finished with exit code 0