关于gRPC原理和核心概念,可以参考下面的文章:

gRPC原理、核心概念和性能分析

这篇文章介绍在IDEA中,如何基于Protobuf 进行序列化、反序列化的简单应用开发。

1. 安装protobuf插件

如下图所示,安装IDEA的Protobuf Support 插件。打开IDEA的Settings,在plugins下搜索 Protobuf Support,然后点击安装即可,安装完成后需要重启IDEA。

idea序列化(Buffers插件以及简单序列化)(1)

maven中的Protocol Buffers插件屏蔽了手动安装Protocol Buffers编译组件的过程,插件会自动安装编译所需要的组件。

2. 在Maven工程的pom文件中,加上protobuf-java依赖包。

<dependency>

<groupId>com.google.protobuf</groupId>

<artifactId>protobuf-java</artifactId>

<version>3.5.1</version>

</dependency>

<dependency>

<groupId>io.grpc</groupId>

<artifactId>grpc-all</artifactId>

<version>1.5.0</version>

</dependency>

3. 在工程的pom文件中,加上Protocol Buffers的Maven插件。

<build>

<extensions>

<extension>

<groupId>kr.motd.maven</groupId>

<artifactId>os-maven-plugin</artifactId>

<version>1.5.0.Final</version>

</extension>

</extensions>

<plugins>

<plugin>

<groupId>org.xolstice.maven.plugins</groupId>

<artifactId>protobuf-maven-plugin</artifactId>

<version>0.5.1</version>

<configuration>

<protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>

<!--默认值-->

<!--<outputDirectory>${project.build.directory}/generated-sources/protobuf/java</outputDirectory>-->

<outputDirectory>${project.build.directory}/generated-sources/protobuf/java</outputDirectory>

<!--设置是否在生成java文件之前清空outputDirectory的文件,默认值为true,设置为false时也会覆盖同名文件-->

<clearOutputDirectory>true</clearOutputDirectory>

<protocArtifact>

com.google.protobuf:protoc:3.5.1:exe:${os.detected.classifier}

</protocArtifact>

<pluginId>grpc-java</pluginId>

<pluginArtifact>

io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}

</pluginArtifact>

</configuration>

<executions>

<execution>

<goals>

<goal>compile</goal>

<goal>compile-custom</goal>

</goals>

</execution>

</executions>

</plugin>

</plugins>

</build>

os-maven-plugin为当前操作系统和体系结构自动生成分类器。

${os.detected.classifier} 的值是由 ${os.detected.name}-${os.detected.arch} 构成的。

${os.detected.name}的值是由${os.name}转化而来的。

${os.detected.arch}的值是由${os.arch}转化而来的。

利用protobuf-maven-plugin的configuration标签下可以配置各种属性,如protoSourceRoot 标签为配置 proto的源IDL 文件,默认地址为${project.basedir}/src/main/proto;outputDirectory 标签为配置编译后输出的文件地址。

idea序列化(Buffers插件以及简单序列化)(2)

查看Maven插件,看到protobuf 下面的命令,表示maven 插件已经生效。

idea序列化(Buffers插件以及简单序列化)(3)

4. 编写protobuf代码。

在/src/main/proto 目录下创建一个文件 person.proto,如下所示。

syntax = "proto3";

option java_package = "cn.springcloud.proto";

option java_outer_classname = "PersonModel";

message Person {

int32 id = 1;

string name = 2;

string email = 3;

}

IDL代码说明:

  • syntax 指定了 Protocol Buffers的版本;
  • option java_package 指定了生成类的包名;
  • option java_outer_classname 指定了生成类的名称。
5. 编译protobuf文件

可以借助IDEA 来执行 mvn protobuf:compile 命令,点击 Plugins下的protobuf的protobuf:compile 命令即可。

idea序列化(Buffers插件以及简单序列化)(4)

上述操作,即可生成 PersonModel 类。

idea序列化(Buffers插件以及简单序列化)(5)

6. 最后编写一个简单的示例应用。

演示如何使用ProtoBuf 做序列化和反序列化一个Java对象。

和使用JSON进行序列化和反序列化类似。采用 Protocol Buffer 序列化的数据可读性很差,但是数据体积小,所以能够大幅提高传输效率。

package cn.springcloud;

import cn.springcloud.proto.PersonModel;

import com.google.protobuf.InvalidProtocolBufferException;

public class PersonUseCase {

public static void main(String[] args) {

PersonModel.Person forezp= PersonModel.Person.newBuilder()

.setId(1)

.setName("forezp")

.setEmail("xxxxx@163.com").build();

for(byte b : forezp.toByteArray()){

System.out.print(b);

}

System.out.println("\n" "bytes长度" forezp.toByteString().size());

System.out.println("===== forezp Byte 结束 =====");

System.out.println("===== forezp 反序列化生成对象开始 =====");

PersonModel.Person forezpCopy = null;

try {

forezpCopy = PersonModel.Person.parseFrom(forezp.toByteArray());

} catch (InvalidProtocolBufferException e) {

e.printStackTrace();

}

System.out.print(forezpCopy.toString());

System.out.println("===== forezp 反序列化生成对象结束 =====");

}

}

输出结果:

idea序列化(Buffers插件以及简单序列化)(6)

,