在你的Spring应用程序中添加Grpc
在前面的例子中,我们有一个Java应用程序正在启动一个http服务器,在这个Java进程中运行一个GRPC应用程序。
如果你使用Spring等框架,你可能会想知道如何实现Grpc和Spring的集成。
有一些库可以做到这一点,我们将使用来自io.github.lognet的grpc-spring-boot-starter。
我们将从依赖性开始。我们确实需要导入我们在之前的例子中使用的gRPC生成插件。
<dependencies>
<dependency>
<groupId>io.github.lognet</groupId>
<artifactId>grpc-spring-boot-starter</artifactId>
<version4.5.8</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.17.2:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.39.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
幕后发生的事情:
- Spring环境启动
- gRPC服务器启动
- 带有@GRpcService注释的Spring服务被选中并注册到gRPC服务器上
- 安全性和其他基于过滤的组件被集成到相应的gRPC ServerInterceptor中。
因此,我们期望用GRpcServices和ServerInterceptor来代替控制器,来代替过滤器。
让我们来添加proto文件。我们将使用与前一个例子相同的proto。
其位置是 src/main/proto/Order.proto,内容是
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.egkatzioura.order.v1";
service OrderService {
rpc ExecuteOrder(OrderRequest) returns (OrderResponse) {};
}
message OrderRequest {
string email = 1;
string product = 2;
int32 amount = 3;
}
message OrderResponse {
string info = 1;
}
正如预期的那样,mvn清洁安装将生成gRPC类。现在我们应该创建spring服务。
package com.gkatzioura.order.impl;
import com.egkatzioura.order.v1.OrderRequest;
import com.egkatzioura.order.v1.OrderResponse;
import com.egkatzioura.order.v1.OrderServiceGrpc;
import io.grpc.stub.StreamObserver;
import org.lognet.springboot.grpc.GRpcService;
@GRpcService
public class OrderServiceImpl extends OrderServiceGrpc.OrderServiceImplBase{
@Override
public void executeOrder(OrderRequest request, StreamObserver<OrderResponse> responseObserver) {
OrderResponse response = OrderResponse.newBuilder()
.setInfo("Hi "+request.getEmail()+", you order has been executed")
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
同时让我们添加主类
package com.gkatzioura.order;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Spring上下文被启动了,@GRpcService注释的服务也开始了。
默认情况下,端口为6565
让我们运行与前一个例子中相同的客户端。
package com.gkatzioura.order;
import com.egkatzioura.order.v1.Order;
import com.egkatzioura.order.v1.OrderRequest;
import com.egkatzioura.order.v1.OrderResponse;
import com.egkatzioura.order.v1.OrderServiceGrpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
public class ApplicationClient {
public static void main(String[] args) {
ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 6565)
.usePlaintext()
.build();
OrderServiceGrpc.OrderServiceBlockingStub orderServiceBlockingStub
= OrderServiceGrpc.newBlockingStub(managedChannel);
OrderRequest orderRequest = OrderRequest.newBuilder()
.setEmail("hello@word.com")
.setProduct("no-name")
.setAmount(3)
.build();
OrderResponse orderResponse = orderServiceBlockingStub.executeOrder(orderRequest);
System.out.println("Received response: "+orderResponse.getInfo());
managedChannel.shutdown();
}
}
响应是预期的那样。我们确实连接到了服务器,并得到了一个响应。我们不必向gRPC服务器手动注册服务,因为spring为我们做了这个。