Java generated-code gRPC

371 阅读1分钟

在使用gRPC时,我们会使用proto3来定义message与service。此处声明Student.proto如下:

syntax = "proto3";
package com.lvcp.proto;
option java_package = "com.lvcp.proto";
option java_outer_classname = "StudentProto";
option java_multiple_files = true;

// proto 中所有方法的参数与返回值必须是一个 message
service StudentService {  
    // 单请求-单响应  
    rpc GetRealName(MyRequest) returns (MyResponse) {}

    // 单请求-流响应
    rpc GetStudentsByAge(StudentRequest) returns (stream StudentResponse) {} 
 
    // 流请求-单响应  
    rpc GetStudentWrapperByAges(stream StudentRequest) returns (StudentResponseList) {}  

    // 流请求-流响应  
    rpc BiTalk(stream StreamRequest) returns (stream StreamResponse) {}
}

message MyRequest {  
    string name = 1;
}
message MyResponse {  
    string name = 1;
}
message StudentResponse {  
    string name = 1;  
    int32 age = 2;  
    string city = 3;
}
message StudentRequest {  
    int32 age = 1;
}
message StudentResponseList {  
    repeated StudentResponse studentResponse = 1;
}
message StreamRequest {  
    string request_info = 1;
}
message StreamResponse {  
    string response_info = 1;
}

生成路径问题

生成代码时所用的插件如何生成等只需看官方文档即可:github.com/grpc/grpc-j…

此处只说明在使用过程中遇到的问题与解决。

下面是build.gradle中对protubuf的配置:

protobuf {    
    generatedFilesBaseDir = "$projectDir/src"    
    protoc {        
        artifact = "com.google.protobuf:protoc:3.12.0"    
    }    
    
    plugins {        
        grpc {            
            artifact = 'io.grpc:protoc-gen-grpc-java:1.33.1'        
            }    
        }    
        generateProtoTasks {        
            all()*.plugins {            
                grpc {                
                    outputSubDir = 'java'             
                }        
            }    
        }
}

其中特别说明generatedFilesBaseDir、outputSubDir两个属性:

  • generatedFilesBaseDir:输出目录的根目录名,可以自己改变名字查看效果, 会将所有的message生成到src/main/java下,之后的包名在.proto文件的java_package属性中指定。
  • outputSubDir: 指定生成grpc方法的目录, 默认是grpc,根目录为generatedFilesBaseDir

进到源码中一探究竟:

com.google.protobuf.gradle.ProtobufConfigurator#generatedFilesBaseDir:

/** 
 * The base directory of generated files. The default is 
 * "${project.buildDir}/generated/source/proto". 
 */
String generatedFilesBaseDirpublic 
ProtobufConfigurator(Project project, FileResolver fileResolver) {  
    this.project = project  
    if (Utils.isAndroidProject(project)) {    
        tasks = new AndroidGenerateProtoTaskCollection()  
    } else {    
        tasks = new JavaGenerateProtoTaskCollection()  
    }  
    tools = new ToolsLocator(project)  
    taskConfigClosures = []  
    generatedFilesBaseDir = "${project.buildDir}/generated/source/proto"
}

可以看到generatedFilesBaseDir该属性的默认为 "project.buildDir/generated/source/proto"也就是会讲所有message的生成类存入build/generated/source/proto/{project.buildDir}/generated/source/proto" 也就是会讲所有message的生成类存入build/generated/source/proto/java_package包下。

将其修改为generatedFilesBaseDir = "projectDir/src",即会存入src/main/java/projectDir/src",即会存入src/main/java/java_package。