1. 概述

本教程将带你探索如何使用 Spring gRPC 项目构建包含 gRPC 服务器的 Spring 应用。通过这个项目,我们既能享受 Spring 的常规优势(如快速开发和依赖注入),又能获得构建 gRPC 服务器、消息和客户端的简单粗暴方案。

2. 项目搭建

首先,我们使用 Spring Initializr 生成示例项目。只需在依赖列表中选择 Spring gRPC 即可。在开发环境中打开下载的文件夹后,你会找到包含所需依赖的 pom.xml 文件,以及包含应用主方法的 Application.java 文件。贴心的是,还自动生成了 proto 文件夹,下一节会用到。

如果要在现有应用中添加 gRPC 服务器,需手动添加以下依赖:

<dependency>
    <groupId>io.grpc</groupId>
    <artifactId>grpc-services</artifactId>
    <version>1.72.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.grpc</groupId>
    <artifactId>spring-grpc-spring-boot-starter</artifactId>
    <version>0.8.0</version>
</dependency>

⚠️ 注意:Spring gRPC 目前仅支持 Spring Boot 3.4.x 和 3.5.x 版本。

除了依赖,我们还需要构建插件从 Proto 文件生成类和接口。Spring Initializr 自动提供的是 protobuf-maven-plugin,其他插件同样可用。

pom.xml 中添加插件配置:

<plugin>
    <groupId>org.xolstice.maven.plugins</groupId>
    <artifactId>protobuf-maven-plugin</artifactId>
    <version>0.6.1</version>
    <configuration>
        <protocArtifact>com.google.protobuf:protoc:4.30.2:exe:${os.detected.classifier}</protocArtifact>
        <pluginId>grpc-java</pluginId>
        <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.72.0:exe:${os.detected.classifier}</pluginArtifact>
    </configuration>
    <executions>
        <execution>
            <id>compile</id>
            <goals>
                <goal>compile</goal>
                <goal>compile-custom</goal>
            </goals>
            <configuration>
                <pluginParameter>jakarta_omit,@generated=omit</pluginParameter>
            </configuration>
        </execution>
    </executions>
</plugin>

3. 定义 Proto 文件

现在基础结构已就绪,开始创建 gRPC 服务和消息。我们将实现一个仅支持乘法运算的基础计算器

在步骤 2 生成的 proto 文件夹中,创建 calculator.proto 文件。首先设置语法和选项:

syntax = "proto3";

option java_multiple_files = true;
option java_package = "org.springframework.grpc.calculator.proto";
option java_outer_classname = "CalculatorProto";
  • syntax 指定使用 Protocol Buffers 的 proto3 版本
  • java_multiple_files 指示编译器为每个服务和消息生成独立 Java 文件
  • java_package 指定生成文件的包路径
  • java_outer_classname 定义 Proto 文件的 Java 包装类名

接着定义包含两个乘数的 Request 消息:

message Request {
  int32 firstValue = 1;
  int32 secondValue = 2;
}

然后定义返回结果的 Response 消息:

message Response {
  int32 result = 1;
}

最后定义服务接口:

service Calculator {
  rpc Multiply(Request) returns (Response) {}
}

该服务名为 Calculator,包含一个 Multiply 方法:接收 Request 返回 Response

4. 生成服务和消息接口

gRPC 功能框架已定义完毕,现在通过以下命令生成所需源文件

./mvnw clean package

执行后将在 target 文件夹生成:

  • RequestResponse 消息的具体实现类
  • 服务抽象基类 CalculatorGrpc.CalculatorImplBase(需继承并实现其 Multiply 方法)

5. 实现具体服务

下一步是继承生成的基类并完整实现 Multiply 方法。创建名为 GrpcCalculatorService 的服务类:

@Service
public class GrpcCalculatorService extends CalculatorGrpc.CalculatorImplBase {}

重写 multiply 方法并添加乘法逻辑:

@Override
public void multiply(Request req, StreamObserver<Response> responseObserver) {
    Response reply = Response.newBuilder().setResult(req.getFirstValue() * req.getSecondValue()).build();
    responseObserver.onNext(reply);
    responseObserver.onCompleted();
}

方法签名提供两个关键参数

  • Request:Proto 文件中定义的请求对象
  • StreamObserver<Response>:用于传递响应的流观察器

实现步骤:

  1. 通过自动生成的 builder 创建包含计算结果的 Response 对象
  2. 使用 onNext() 发送响应
  3. 调用 onCompleted() 标志处理完成

6. 运行和测试服务

启动服务有两种方式:

  • 通过 IDE 运行 Application.java 的主方法
  • 命令行启动:
./mvnw spring-boot:run

服务启动成功后,可通过命令行测试。这里使用 gRPCurl 工具(其他工具如 grpcui 也可用):

grpcurl -d '{"firstValue":7, "secondValue":6}' -plaintext localhost:9090 Calculator.Multiply

参数说明:

  • -d:传递请求消息(包含两个乘数)
  • -plaintext:使用明文通信(生产环境应启用 TLS)
  • localhost:9090:服务地址(可在 application.properties 中修改)
  • Calculator.Multiply:指定调用的服务和方法

预期响应:

{
  "result": 42
}

7. 总结

本教程介绍了 Spring gRPC 项目的基础用法:

  1. ✅ 通过 Spring Initializr 快速搭建项目
  2. ✅ 使用 Proto 文件定义服务和消息结构
  3. ✅ 通过 Maven 插件自动生成代码骨架
  4. ✅ 实现服务接口创建完整计算器功能
  5. ✅ 命令行测试验证服务正确性

这是用最少代码将 gRPC 服务器集成到 Spring 生态的快捷方案。完整示例代码可在 GitHub 获取。