记录下一个简单的proto文件生成java代码案例。
步骤1
首先生成一个简单的maven项目,可通过 mvn archetype:generate 命令生成。
mvn archetype:generate
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:3.2.1:generate (default-cli) > generate-sources @ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:3.2.1:generate (default-cli) < generate-sources @ standalone-pom <<<
[INFO]
[INFO]
[INFO] --- maven-archetype-plugin:3.2.1:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
[WARNING] No archetype found in remote catalog. Defaulting to internal catalog
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: internal -> org.apache.maven.archetypes:maven-archetype-archetype (An archetype which contains a sample archetype.)
2: internal -> org.apache.maven.archetypes:maven-archetype-j2ee-simple (An archetype which contains a simplifed sample J2EE application.)
3: internal -> org.apache.maven.archetypes:maven-archetype-plugin (An archetype which contains a sample Maven plugin.)
4: internal -> org.apache.maven.archetypes:maven-archetype-plugin-site (An archetype which contains a sample Maven plugin site.
This archetype can be layered upon an existing Maven plugin project.)
5: internal -> org.apache.maven.archetypes:maven-archetype-portlet (An archetype which contains a sample JSR-268 Portlet.)
6: internal -> org.apache.maven.archetypes:maven-archetype-profiles ()
7: internal -> org.apache.maven.archetypes:maven-archetype-quickstart (An archetype which contains a sample Maven project.)
8: internal -> org.apache.maven.archetypes:maven-archetype-site (An archetype which contains a sample Maven site which demonstrates
some of the supported document types like APT, XDoc, and FML and demonstrates how
to i18n your site. This archetype can be layered upon an existing Maven project.)
9: internal -> org.apache.maven.archetypes:maven-archetype-site-simple (An archetype which contains a sample Maven site.)
10: internal -> org.apache.maven.archetypes:maven-archetype-webapp (An archetype which contains a sample Maven Webapp project.)
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 7:
Define value for property 'groupId': com.fsyy
Define value for property 'artifactId': demo
Define value for property 'version' 1.0-SNAPSHOT: :
Define value for property 'package' com.fsyy: : com.fsyy.demo
Confirm properties configuration:
groupId: com.fsyy
artifactId: demo
version: 1.0-SNAPSHOT
package: com.fsyy.demo
Y: : Y
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.1
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: basedir, Value: /***/***/proto/demo/maven-project
[INFO] Parameter: package, Value: com.fsyy.demo
[INFO] Parameter: groupId, Value: com.fsyy
[INFO] Parameter: artifactId, Value: demo
[INFO] Parameter: packageName, Value: com.fsyy.demo
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /***/***/proto/demo/maven-project/demo
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 24.946 s
[INFO] Finished at: 2023-12-26T14:34:00+08:00
[INFO] ------------------------------------------------------------------------
其中,项目number默认7,直接回车
groupId根据自己的实际情况填写,我填为com.fsyy
artifactId根据自己的实际情况填写,我填为demo
version默认1.0-SNAPSHOT,直接回车
package默认为你自己填写的groupId,我个人习惯加上artifactId,填为com.fsyy.demo
然后确认填Y回车即可生成一个maven项目。
步骤2
打开生成的maven项目中的pom.xml配置文件,内容为
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.fsyy</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
参考gRPC官方文档代码示例配置
https://grpc.io/docs/languages/java/quickstart/
git clone -b v1.60.0 --depth 1 https://github.com/grpc/grpc-java
拉取代码后找到项目根目录中的pom.xml,参考修改
我修改后的pom.xml配置文件如下
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.fsyy</groupId>
<artifactId>demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<grpc.version>1.16.1</grpc.version>
<protoc.version>3.5.1-1</protoc.version>
<protobuf.version>3.24.0</protobuf.version>
<grpc.version>1.60.0</grpc.version><!-- CURRENT_GRPC_VERSION -->
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-bom</artifactId>
<version>${grpc.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-services</artifactId>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>${protobuf.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<extensions>
<!-- 兼容eclipse和netbeans中protobuf代码生成插件 -->
<!-- 插件主要是为了识别不同的操作系统,这样插件可以根据不同的平台加载不同protoc编译器文件 -->
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.1</version>
</extension>
</extensions>
<plugins>
<!-- grpc代码生成插件 -->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<!-- .proto 文件路径 -->
<!--<protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot>-->
<!-- 输出路径 -->
<!--<outputDirectory>${project.basedir}/src/main/java</outputDirectory>-->
<!--设置是否在生成java文件之前清空outputDirectory的文件,默认值为true,设置为false时也会覆盖同名文件-->
<clearOutputDirectory>true</clearOutputDirectory>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}
</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
步骤3
在项目代码的src/main/java下新建一个proto目录(proto文件默认存放位置,可在pom文件中修改),然后添加一个proto示例文件,我的命名为helloworld.proto,文件内容为
// 使用proto3语法
syntax = "proto3";
// proto包名
package helloworld;
// 生成多个Java文件
option java_multiple_files = true;
// 指定Java包名
option java_package = "com.fsyy.demo.hello";
// 指定Java输出类名
// option java_outer_classname = "HelloworldProto";
// gRPC服务定义
service Hello {
// gRPC服务方法定义
rpc sayHello (HelloRequest) returns (HelloReply) {}
}
// 请求参数定义
message HelloRequest {
string name = 1;
}
// 响应结果定义
message HelloReply {
string message = 1;
}
步骤4
执行编译命令,如果你用IDEA进行编程,可以在maven模块中找到protobuf插件,双击protobuf:compile进行执行。
执行后,你能在target/generated-sources中找到生成的java代码,如图
当然,也可以在项目根目录下执行mvn compile命令,也是会生成相应的java代码,这具体和maven配置的构建任务目标有关,绑定了compile阶段,此文不进行深入分析。
其它说明
可以取消pom文件中的
<outputDirectory>${project.basedir}/src/main/java</outputDirectory>
这栏注释,然后执行编译步骤,就能在src/main/java目录下生成目标代码了。不过建议把clearOutputDirectory设置为false,这样就避免了清空src/main/java目录。例如项目中App.java文件就在src/main/java目录下,如果默认clearOutputDirectory为true,则此文件在编译时也会清空。
<clearOutputDirectory>false</clearOutputDirectory>
补充:
如果通过IDEA的插件执行protobuf:compile命令,只会生成protobuf序列化相关的代码,而不会生成grpc那部分代码(对应protoc-gen-grpc-java这个插件),若要生成grpc部分代码,还得执行protobuf:compile-custom命令。故最好使用mvn compile命令进行代码生成。偷个懒就不截图了。