


个人主页:手握风云
目录
[一、初始 ProtoBuf](#一、初始 ProtoBuf)
[1.1. 序列化与反序列化](#1.1. 序列化与反序列化)
[1. 核心定义](#1. 核心定义)
[2. 使用场景](#2. 使用场景)
[1.2. ProtoBuf 基础介绍](#1.2. ProtoBuf 基础介绍)
[1.3. 使用特点与完整工作流程](#1.3. 使用特点与完整工作流程)
[二、ProtoBuf 安装](#二、ProtoBuf 安装)
[2.1. Windows 环境安装](#2.1. Windows 环境安装)
[2.2. CentOS 环境安装](#2.2. CentOS 环境安装)
[三、ProtoBuf 快速上手](#三、ProtoBuf 快速上手)
[3.1. 引入 Maven 依赖](#3.1. 引入 Maven 依赖)
[3.2. 编写 .proto 协议文件](#3.2. 编写 .proto 协议文件)
[1. 目录与文件命名规范](#1. 目录与文件命名规范)
[2. .proto 文件基础语法配置](#2. .proto 文件基础语法配置)
[3. 定义 Message](#3. 定义 Message)
[4. 定义消息字段](#4. 定义消息字段)
[3.3. 编译 .proto 文件](#3.3. 编译 .proto 文件)
[1. 命令行编译](#1. 命令行编译)
[2. Maven 插件编译](#2. Maven 插件编译)
[3.4. 生成的 Java 类核心结构](#3.4. 生成的 Java 类核心结构)
[3.5. 实现序列化与反序列化](#3.5. 实现序列化与反序列化)
一、初始 ProtoBuf
1.1. 序列化与反序列化
1. 核心定义
- 序列化:把内存中的对象转换为字节序列的过程。
- 反序列化:把字节序列还原为原始对象的过程,是序列化的逆向操作。
2. 使用场景
数据持久化存储:将内存中的对象状态保存到本地文件、数据库中。网络数据传输:网络无法直接传输编程语言对象,需先将对象序列化为字节流发送;接收端再通过反序列化还原为对象(典型场景:Socket 网络编程)。
1.2. ProtoBuf 基础介绍

支持 Java、C++、Python 等主流编程语言,可在不同操作系统、运行平台上使用。相较于 XML,序列化后数据体积更小、编解码速度更快、语法与使用逻辑更简单。还具有高扩展性与兼容性,后续迭代、修改数据结构时,不会影响线上正在运行的、基于旧数据结构的程序。
1.3. 使用特点与完整工作流程
ProtoBuf 并非直接手写序列化逻辑,而是基于协议文件 + 编译器自动生成代码的模式工作,整体流程固定。

ProtoBuf 采用协议文件结合编译器自动生成代码的工作模式,使用时首先由开发者编写 .proto 协议文件来定义数据结构,再借助 protoc 编译器对协议文件进行编译,工具会自动生成对应编程语言的实体类以及配套工具方法,其中涵盖了序列化、反序列化、字段读写等各类接口,最后业务代码直接依赖编译生成的代码开展开发工作,无需手动编写协议解析逻辑,就能完成对象操作与数据编解码。
它的标准使用流程分为三个环节:第一步是编写 .proto 文件,该文件用于自定义结构化对象及其属性字段,相当于约定好数据交互与存储所使用的协议格式;第二步是使用 protoc 编译器编译 .proto 文件,解析协议内容并自动生成 Java 等目标语言代码;第三步是在业务代码中调用已生成的代码,完成字段的赋值与读取,同时实现对象与字节序列之间的序列化和反序列化操作。
二、ProtoBuf 安装
2.1. Windows 环境安装
官方下载地址:https://github.com/protocolbuffers/protobuf/releases。无需强制下载最新版。



将解压目录中的 bin 文件夹路径,添加到系统 / 用户环境变量的 Path 列表中。然后在 cmd 终端里面输入 protoc --version,检验是否安装成功。

2.2. CentOS 环境安装
bash
sudo yum install autoconf automake libtool curl make gcc-c++ unzip

我们还是在之前的 Github 仓库中下载同样的 Protocol Buffers 版本。

bash
# 下载命令
wget https://github.com/protocolbuffers/protobuf/releases/download/v21.11/protobuf-all-21.11.zip
bash
# 解压并进入目录
unzip protobuf-all-21.11.zip
cd protobuf-21.11

bash
# 执行 configure,选择安装路径
./configure
编译、测试、正式安装,单步执行时间约 15 分钟。
bash
make # 源码编译
make check # 单元测试校验
sudo make install # 正式安装
最后还是输入 protoc --version 检验是否安装成功。

三、ProtoBuf 快速上手
3.1. 引入 Maven 依赖
XML
<!-- Source: https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf_version}</version>
<scope>compile</scope>
</dependency>
使用 ProtoBuf 首先需要在 pom.xml 引入官方 Java 客户端依赖,依赖版本必须与本地 protoc 编译器版本保持一致。
3.2. 编写 .proto 协议文件
.proto 是 ProtoBuf 的协议定义文件,用于描述结构化数据(消息、字段、类型),是整个使用流程的入口。
1. 目录与文件命名规范
所有 .proto 文件统一存放于项目 src/main/proto 目录下;全小写字母,多个单词用下划线分隔,如 contacts;单行注释://,多行注释:/**/。
2. .proto 文件基础语法配置
必须在注释之外的第一行声明语法版本,这里使用主流的 proto3。如果为声明,则编译器默认使用 proto2。
syntax = "proto3";
package 命名空间(可选):用于区分不同协议、避免消息类名冲突,建议配置。
package start;
Java 专属 Option 配置:
| 配置项 | 作用 |
|---|---|
| java_multiple_files | true:每个 message 生成独立 Java 文件;false:所有内容合并到一个类中 |
| java_package | 强制指定编译后 Java 类的包名,优先级高于 package 关键字 |
| java_outer_classname | 定义协议总入口包装类名称 |
java
option java_multiple_files = true;
option java_package = "com.example.start";
option java_outer_classname = "ContactProtos";
3. 定义 Message
message 对应 Java 中的实体对象,用来描述业务数据结构。命名规范使用大驼峰命名。
java
message 消息名 {
// 字段定义
}
4. 定义消息字段
字段基础格式:字段类型 字段名 = 字段唯一编号; 字段名采用全小写 + 下划线的格式。字段唯一编号是核心标识,一旦上线禁止修改。
java
// 定义联系人
message PeopleInfo {
// 字段类型 字段名 = 字段唯一编号
string name = 1;
int32 age = 2;
}
| .proto 类型 | 说明 | 对应 Java 类型 |
|---|---|---|
| string | 字符串(UTF-8/ASCII) | String |
| int32 | 变长编码整型,负数效率低 | int |
| bool | 布尔类型 | boolean |
| float/double | 浮点型 | float/double |
| bytes | 任意字节序列 | ByteString |
字段编号强制规则 字段编号的合法取值范围为 1 ~ 536,870,911,其中 19000 ~ 19999 是 Protobuf 内部预留区间,开发者不能使用该区间内的编号,否则编译过程中会出现告警。从编码效率角度出发也有对应的使用建议,编号 1 至 15 仅需 1 字节完成编码,适合分配给项目里高频使用的字段;编号 16 至 2047 需要占用 2 字节编码,更适合分配给使用频次较低的字段。
3.3. 编译 .proto 文件
编译的核心作用:通过 protoc 编译器,将 .proto 协议文件自动生成 Java 实体类,生成的类内置序列化、反序列化、字段读写等方法。
1. 命令行编译
命令格式:
bash
protoc [--proto_path=协议文件目录] --java_out=Java输出目录 协议文件路径
bash
protoc -I src/main/proto/start --java_out=src/main/java contacts.proto
2. Maven 插件编译
XML
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<!-- 本地 protoc.exe 编译器绝对路径(必须配置) -->
<protocExecutable>C:\xxx\protoc-21.11-win64\bin\protoc.exe</protocExecutable>
<!-- .proto 文件根目录 -->
<protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>
<!-- 生成 Java 文件的输出目录 -->
<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
<!-- 禁止清空输出目录,防止误删项目代码 -->
<clearOutputDirectory>false</clearOutputDirectory>
</configuration>
</plugin>
在 Maven 工具栏执行 protobuf:compile 指令,自动完成编译。

因为我们之前配置了 java_multiple_files = true,编译后生成3 个独立 Java 文件:
- ContactsProtos.java:协议总包装类;
- PeopleInfo.java:联系人消息对应的实体主类(核心使用类);
- PeopleInfoOrBuilder.java:字段读取接口。
3.4. 生成的 Java 类核心结构
PeopleInfo 主类:
- 继承 GeneratedMessageV3,只有 get 方法,无 set 方法;
- 内置 parseFrom() 系列静态方法:反序列化核心方法(字节数组 / 输入流 → 对象);
- 内置 newBuilder() 静态方法:创建对象构造器 Builder;
- 继承父接口 MessageLite,拥有 toByteArray()、writeTo():序列化核心方法(对象 → 二进制字节)。
内部 Builder 静态类:
- 提供 setXXX() / getXXX() / clearXXX() 方法:读写、清空字段;
- 提供 build() 方法:将 Builder 构建为不可变的 PeopleInfo 实体对象。
3.5. 实现序列化与反序列化
java
package com.example.start;
import com.google.protobuf.InvalidProtocolBufferException;
import java.util.Arrays;
public class FastStart {
public static void main(String[] args) {
// 使用 Builder 构建联系人对象,设置字段值
PeopleInfo people = PeopleInfo.newBuilder()
.setName("张三")
.setAge(21)
.build();
// 序列化:对象 → 二进制字节数组
byte[] byteData = people.toByteArray();
System.out.println("序列化二进制数组:" + Arrays.toString(byteData));
System.out.println("序列化数组字节大小:" + byteData.length);
// 反序列话:二进制字节数组 → 原对象
try {
PeopleInfo newPeople = PeopleInfo.parseFrom(byteData);
System.out.println("反序列化后名字:" + newPeople.getName());
System.out.println("反序列化后年龄:" + newPeople.getAge());
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
}
}
