初识ProtoBuf
网路通信和数据交换的序列化协议常用的有JSON、XML
JSON作为目前主流的序列化框架,在spring、springboot中广泛使用,并且在接口的开发中,基本都是使用JSON作为数据的接收和处理,JSON相对已经很快了,并且体积也较小,但是Google推出了一个高性能序列化框架ProtoBuf,比JSON更快的一块序列化框架
ProtoBuf是什么
protocol buffers 是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。
Protocol Buffers 是一种灵活,高效,自动化机制的结构数据序列化方法-可类比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单。
总的来说:ProtoBuf比json、xml更小、更快,扩展性更好
ProtoBuf常用类型
| proto类型 | java类型 |
|---|---|
| double | double |
| float | float |
| int32 | int |
| int64 | long |
| bool | boolean |
| string | String |
| enum | enum |
上面的几种常用类型分别是在ProtoBuf中的类型与Java中的类型对应关系,可以看到基本上类型都相同,定义proto文件的时候需要使用proto类型,在proto文件编译为java文件的时候,对应的使用的为java中的类型
ProtoBuf访问修饰符
-
optional可选修饰符,表示该字段是非必填字段,如果没有传递该字段的数据,则会有默认值
-
require必填字段,表示该字段是必填字段
-
repeated表示该字段是一个列表,等价于集合
Proto文件定义
-
创建
.proto文件 -
定义proto内容
syntax = "proto2"; // 定义proto文件的语法 package test; // 相当于声明命名空间,防止多个文件中相同的message命名冲突 option java_package = "com.demo.bean"; // 编译之后的包名 option java_outer_classname = "PersonProto"; // 编译只有的类名称 message PersonInfo { required int32 id = 1; optional string name = 2; optional string remark = 3; }java_package表示生成java类之后的包名,java_outer_classname表示想要生成Java类的名称,如果没有指定,用protobuf文件名代替(自动转为驼峰形式);package表示当前文件的包,相当于声明命名空间,防止多个文件中相同的message命名冲突
这个proto文件表示定义一个类为
PersonProto,PersonInfo是该类中的一个消息,在该类中可以有多个消息定义,该消息中定义了3个字段。每个字段后面的数字表示该字段的编号,这也是ProtoBuf快的原因,在序列化的时,直接根据序号就可以找到指定的字段,所以每个字段的编号不可以重复
Protobuf3与Protobuf2的区别
-
如何区别是Protobuf3还是protobuf2
在
.proto文件的第一行需要声明当前.proto文件使用到proto版本syntax = "proto2"; // 声明proto2版本的proto文件 syntax = "proto3"; // 声明proto3版本的proto文件 -
proto3与proto2的区别
-
proto2中定义message中属性时,需要使用required、optional来定义字段的访问权限,如果没有该访问修饰符,在编译的时候报错 -
proto3中去除了required、optional权限修饰,无需定义这两种权限修饰符,直接不用写proto3中的
repeated表示定义数组,所以还是需要定义的 -
proto3中增加了数据类型map<int32, bool>
-
编译proto文件
-
下载
protoc.exe文件下载指定的版本的环境的安装包,即可获取到对应的
protoc.exe -
使用命令编译定义的
.proto文件protoc.exe --java_out=. Person.proto--java_out==.表示将输出的java文件放到当前目录下(也可以指定目录),编译的.proto文件为Person.proto
执行命令之后,就可以看到生成的java文件放到定义的指定目录下
下一篇文件介绍如何在Java中使用ProtoBuf~~