Spring gRPC 0.4.0 带来巨大便利!

工程 | Josh Long | 2025年3月4日 | ...

注意:您可以在这里找到本博客的工作代码

备受瞩目(尽管仍处于实验阶段)的 Spring gRPC 项目发布了新版本:0.4.0。我不会深入探讨所有新功能,但我只想强调我使用它时是多么兴奋,并将引导您一步步走向 gRPC 的乐趣。无数细微之处都恰到好处,使其成为我使用 gRPC 以来最流畅的体验!

我访问了Spring Initializr,并选择了 GRPCGraalVMWeb。我喜欢 Maven,但您可以随心所欲。我当然选择了 Java 23,因为 Java 24 即将在一两周内发布。我认为这篇博客在至少几周内仍会很有趣。具体来说,我正在使用 GraalVM,它是一个 OpenJDK 发行版,支持一些额外的“花招”,包括将 JVM 代码编译成操作系统和架构特定的本地代码。

如果您使用的是与 UNIX 兼容的操作系统(Windows 上的 Cygwin 和适用于 Linux 的 Windows 子系统也算),那么您可以尝试使用 SDKMAN 来安装和管理您的 JDK 版本。我是这样做的:

sdk install java 23.0.2-graalce  

现在,再次提醒:这是 Java 23。Java 24 定于 2025 年 3 月中旬发布!不要掉队。你肯定不想在聚会上被人嘲笑和指指点点吧?升级!

Spring 已经为我们考虑周全了!Spring Initializr 洞察到我正在使用 Servlet 引擎,于是添加了 Spring gRPC、Spring Boot 的 web 支持,以及允许您在 Servlet 容器中托管 gRPC 的桥接器。(默认情况下,Spring gRPC 通过 Netty 运行 gRPC,没有 HTTP 基础。)哦,而且它还为我们选择了 HTTP/2!

Spring Initializr 非常贴心地配置了必要的插件,用于进行代码生成,将 gRPC 协议缓冲区定义转换为我们可以实现的 Java 代码。看到我说方便是什么意思了吗?我们甚至还没有开始编写代码,但我们可以了!

编写任何 gRPC 服务的首要步骤是使用 Google Protocol Buffers 格式定义 schema。然后我们将 schema 转换为 Java 代码,我们可以在自己的服务中实现它。确保您已安装 protoc 编译器。您最好也安装 grpcurl,这是一个方便的工具,用于向 gRPC 端点发出请求。

这是我的 schema。它定义了一个简单的服务,用于枚举和领养 Dogs。

syntax = "proto3";  
option java_multiple_files = true;  
option java_package = "com.example.demo.grpc.impl";  
option java_outer_classname = "AdoptionsProto";  

import "google/protobuf/empty.proto";  

service Adoptions {  

  rpc All(google.protobuf.Empty) returns (DogsResponse){}  

  rpc Adopt(DogAdoptionRequest) returns (google.protobuf.Empty){}  
}  

message Dog {  
  int32 id = 1;  
  string name = 2;  
  string description = 3;  
  string owner = 4;  
}  

message DogAdoptionRequest {  
  int32 dogId = 1;  
  string name = 2;  
}  

message DogsResponse {  
  repeated Dog dogs = 1;  
}  

要生成 Java 代码,运行

./mvnw -DskipTests package  

现在,您已经万事俱备,可以实现您的第一个 gRPC 服务了!

package com.example.demo;  

import com.example.demo.grpc.impl.AdoptionsGrpc;  
import com.example.demo.grpc.impl.Dog;  
import com.example.demo.grpc.impl.DogAdoptionRequest;  
import com.example.demo.grpc.impl.DogsResponse;  
import com.google.protobuf.Empty;  
import io.grpc.stub.StreamObserver;  
import org.springframework.boot.SpringApplication;  
import org.springframework.boot.autoconfigure.SpringBootApplication;  
import org.springframework.stereotype.Service;  

import java.util.List;  

@SpringBootApplication  
public class DemoApplication {  

    public static void main(String[] args) {  
        SpringApplication.run(DemoApplication.class, args);  
    }  
}  

@Service  
class AdoptionsGrpcService extends AdoptionsGrpc.AdoptionsImplBase {  

    @Override  
    public void all(Empty request, StreamObserver<DogsResponse> responseObserver) {  
        responseObserver.onNext(DogsResponse.newBuilder()  
                .addAllDogs(List.of(  
                        Dog.newBuilder().setName("dog1").setDescription("the goodest boy").setOwner("jlong").build(),  
                        Dog.newBuilder().setName("dog2").setDescription("the goodest girl").setOwner("jlong").build()))  
                .build());  
        responseObserver.onCompleted();  
    }  

    @Override  
    public void adopt(DogAdoptionRequest request, StreamObserver<Empty> responseObserver) {  
        System.out.println("Adopting " + request.getName() + " " + request.getDogId());  
        responseObserver.onNext(Empty.getDefaultInstance());  
        responseObserver.onCompleted();  
    }  
}  

要启用虚拟线程,请将以下内容添加到 src/main/resources/application.properties

spring.threads.virtual.enabled=true  

现在,让我们编译一个 GraalVM 本机镜像!

要编译一个运行在您的主机操作系统上的本机镜像,运行

./mvnw -DskipTests -Pnative native:compile  

要创建一个 Docker 镜像(需要 Docker 正在运行),运行

./mvnw -DskipTests -Pnative spring-boot:build-image  

现在,让我们测试一下

grpcurl -plaintext localhost:8080 Adoptions.All  

如果一切顺利,恭喜您构建了您的第一个以 Spring gRPC 为中心的应用!祝您的生产之旅愉快!🚀

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看所有