如何使用Spring Boot搭建gRPC应用并同时实现gRPC与HTTP接口
Spring Boot 单应用同时集成gRPC + HTTP接口实现getBookList操作指南
一、依赖引入
优先使用成熟的starter组件减少配置工作,以Maven项目为例,核心依赖配置如下:
- Spring Web依赖:用于支持HTTP接口能力
- gRPC Spring Boot Starter:无需手动配置gRPC核心组件
- Protobuf编译插件:自动将.proto接口定义转换为Java代码
<!-- Spring Web 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- gRPC Starter 依赖 --> <dependency> <groupId>net.devh</groupId> <artifactId>grpc-spring-boot-starter</artifactId> <version>2.15.0.RELEASE</version> </dependency> <!-- Protobuf 编译插件,放在build->plugins节点下 --> <plugin> <groupId>io.github.lognet</groupId> <artifactId>grpc-spring-boot-starter-maven-plugin</artifactId> <version>4.5.4</version> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin>
二、定义Protobuf接口
在src/main/proto目录下新建book.proto文件,定义gRPC的服务结构和数据模型:
syntax = "proto3"; option java_package = "com.example.library.grpc"; option java_outer_classname = "BookProto"; option java_multiple_files = true; // 图书实体 message Book { int64 id = 1; string name = 2; string author = 3; } // 获取图书列表请求 message GetBookListRequest { string author = 1; // 可选筛选参数 } // 获取图书列表响应 message GetBookListResponse { repeated Book books = 1; } // gRPC服务定义 service BookService { rpc getBookList(GetBookListRequest) returns (GetBookListResponse); }
执行Maven的compile命令后,会自动在target目录下生成对应的gRPC服务接口、实体类代码。
三、抽象公共业务逻辑
将图书列表查询的核心逻辑抽成公共Service,避免HTTP和gRPC接口重复开发:
@Service public class BookBizService { // 模拟数据库查询逻辑,可替换为实际的DAO操作 public List<com.example.library.entity.Book> getBookList(String author) { List<com.example.library.entity.Book> bookList = new ArrayList<>(); bookList.add(new com.example.library.entity.Book(1L, "Java编程思想", "Bruce Eckel")); bookList.add(new com.example.library.entity.Book(2L, "Spring实战", "Craig Walls")); // 可自行添加按作者筛选的逻辑 return bookList; } }
四、分别实现两类接口
1. HTTP接口实现
直接编写常规的Spring MVC Controller即可:
@RestController @RequestMapping("/api/book") public class BookController { @Autowired private BookBizService bookBizService; @GetMapping("/list") public List<com.example.library.entity.Book> getBookList(String author) { return bookBizService.getBookList(author); } }
2. gRPC接口实现
实现自动生成的gRPC服务基类,添加@GrpcService注解即可被框架自动识别:
@GrpcService public class BookGrpcServiceImpl extends BookServiceGrpc.BookServiceImplBase { @Autowired private BookBizService bookBizService; @Override public void getBookList(GetBookListRequest request, StreamObserver<GetBookListResponse> responseObserver) { // 调用公共业务逻辑 List<com.example.library.entity.Book> bizBookList = bookBizService.getBookList(request.getAuthor()); // 转换为Proto定义的实体格式 List<Book> protoBookList = bizBookList.stream().map(bizBook -> Book.newBuilder() .setId(bizBook.getId()) .setName(bizBook.getName()) .setAuthor(bizBook.getAuthor()) .build() ).collect(Collectors.toList()); // 构造响应返回 GetBookListResponse response = GetBookListResponse.newBuilder() .addAllBooks(protoBookList) .build(); responseObserver.onNext(response); responseObserver.onCompleted(); } }
五、端口配置
在application.yml中配置两个服务的端口避免冲突:
# HTTP服务端口,默认8080 server: port: 8080 # gRPC服务端口,默认9090 grpc: server: port: 9090
六、验证方式
- HTTP接口:直接访问
http://localhost:8080/api/book/list?author=Bruce即可拿到返回结果 - gRPC接口:用grpcurl或Postman的gRPC功能连接
localhost:9090,调用BookService/getBookList即可拿到结果
提示:单实例部署场景下无需额外配置服务发现,两个协议的服务互不影响。
内容的提问来源于stack exchange,提问作者Dewwrat
相关产品推荐
相关产品推荐

