1. 介绍

protobuf是一种非常流行的开源序列化框架。在很多开源软件中被广泛应用。例如netty4中就有protobuf的编码器。

本节主要参考propobuf官方文档Language Guide (proto3)来对该序列化框架的JAVA中的使用做一些介绍。

2. protobuf3新特性

Protocol Buffers v3.0.0 release note中我们可以看看protobuf3的新特性:

2.1 主要新特性

  1. 移除了required域和用户自定义默认值(类似[default = 1.0]这样的选项没有了)
  2. 移除了unknown域
  3. 移除了extensions,用any类型来替代
  4. 枚举值默认设置为0
  5. 支持map类型
  6. 支持time、dynamic data等等的新标准类型
  7. 支持JSON序列化
  8. 新的标记"syntax",标记使用proto3还是proto2
  9. 多语言支持

更多新特性的描述,可以参考文章 Proto3的语法变化官方说明

PS:没有用户自定义默认值选项是有点坑爹,据说是为了支持其他语言。

3. 生成protbuf可识别的消息类

protobuf只识别其根据proto文件生成的JAVA类。因此,我们首先先定义消息格式,消息格式的文件后缀为 .proto 。之后我们使用protobuf的工具来生成JAVA协议格式类。

3.1 定义消息格式

假设我们有个JAVA的VO需要传输(我们这里用的是canal这个开源中间件里面的对象),其定义可以看 github上的源码:

  1. Canal.java
  2. CanalParameter.java
  3. CanalStatus.java

以上类是我们需要用protobuf传输的消息,根据原始的JAVA类定义,我们下面编写下proto文件。因为我们这里存在一些嵌套关系,我们定义三个proto文件,proto文件的内容见github:

  1. CanalModelProtocol.proto
  2. CanalParameterProtocol.proto

3.2 下载编译好的protobuf来生成java类

protobuf的github仓库下载最新的protoc工具。我们使用protoc工具来生成对应的JAVA类。

根据自己的操作系统平台选择适合自己的protoc:

我的开发环境是WIN的,就直接下载protoc-3.1.0-win32.zip即可。下载好了,把其目录下的bin加入环境变量,方便在任何地方都能调用。

PS: --java_out的值只需要到main/java就够了,因为proto文件里面已经指定了其包名

执行以下命令,生成proto文件对应的JAVA类

#protoc -proto_path=依赖的proto文件所在目录(-proto_path可出现多次指定多个依赖目录,可以缩写为-I) -java_out=java文件产生的目录  最后个选项是使用的proto文件所在目录
protoc -I=C:/dev/protoc-3.1.0-win32/include/google/protobuf -I=C:/JavaProjects/canal/instance/manager/src/main/java/com/alibaba/otter/canal/instance/manager/protocol  --java_out=C:/JavaProjects/canal/instance/manager/src/main/java  C:/JavaProjects/canal/instance/manager/src/main/java/com/alibaba/otter/canal/instance/manager/protocol/CanalModelProtocol.proto

protoc -I=C:/dev/protoc-3.1.0-win32/include/google/protobuf -I=C:/JavaProjects/canal/instance/manager/src/main/java/com/alibaba/otter/canal/instance/manager/protocol  --java_out=C:/JavaProjects/canal/instance/manager/src/main/java  C:/JavaProjects/canal/instance/manager/src/main/java/com/alibaba/otter/canal/instance/manager/protocol/CanalParameterProtocol.proto

4. 使用protobuf来序列化和反序列化

未完待续

参考资料:

  1. Proto3的语法变化
  2. [翻译] Protobuf 语言指南 ( proto 2 )