【囫囵吞枣】如何初始化一个Spring Boot微服务项目 Part 3| 豆包MarsCode AI刷题

40 阅读2分钟

写好ProtoBuf下的接口定义、消息定义后,我们就可以着手将ProtoBuf编译到需要用到它们的服务中了。

4 微服务具体如何实现ProtoBuf定义的服务?

4.1 在pom.xml中定义compile阶段需要的ProtoBuf依赖

.proto文件中定义的service会在Maven的Compile阶段被编译成Java桩代码,其为每个定义的service提供了一个可以继承的类MyServiceImplBase。在编写服务时,只需要继承这个类,然后Override所有在.proto文件中定义的服务方法即可。

“编译成Java桩代码”,这个编译的过程是怎样的呢?我当时在学的时候,脑袋里自然想了两个问题:

  1. 微服务架构里,服务A自己install的时候肯定不能引用别的服务的代码(服务A自己就可以被看成一个“项目”)。那难道要每个服务都维护一批相同的ProtoBuf文件,然后有任何更改都手动在所有服务里同步一遍吗?这显然是不可行的;
  2. 具体需要哪些Maven配置?(这问题好像问了白问……)

首先来看看pom.xml里需要加点什么。

我们可以在父包的pom.xml里添加一些所有服务公用的配置,比如使用ProtoBuf的什么版本之类,这样方便我们统一调整:

<properties>
    <protobuf-java.version>3.19.6</protobuf-java.version>
    <protoc.version>3.22.3</protoc.version>
</properties>

接下来在每个子包内,定义Compile阶段,生成Java桩代码的ProtoBuf文件所在目录以及生成的代码所在目录。

这里我们就需要先解决一下刚才的第一个问题了。我们怎么管理ProtoBuf文件呢?答案是将ProtoBuf文件都放在一个包里,我们可以叫它interface;其它所有的服务都通过在Compile阶段,访问interface包内的ProtoBuf文件的方式,来生成自己服务目录下的Java桩代码

所以这样一来,interface包和别的服务的pom.xml配置就会有不同

<plugin>
    <groupId>org.xolstice.maven.plugins</groupId>
    <artifactId>protobuf-maven-plugin</artifactId>
    <version>0.6.1</version>
    <configuration>
        <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
        <outputDirectory>build/generated/source/proto/main/java</outputDirectory>
        <protocPlugins>
            <protocPlugin>
                <id>dubbo</id>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-compiler</artifactId>
                <version>${dubbo.version}</version>
                <mainClass>org.apache.dubbo.gen.tri.Dubbo3TripleGenerator</mainClass>
            </protocPlugin>
        </protocPlugins>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
            </goals>
        </execution>
    </executions>
</plugin>

在上面的一大串xml配置里:

  • protoc.version变量由父包继承而来,这样方便管理各个服务的protobuf版本;
  • 编译得到的Java桩代码放置在与main/java同级的main/build目录下,与需要我们自己编辑的代码分开;
  • 我们使用triple协议进行通信,所以选用了Dubbo3TripleGenerator。

接下来,我们定义每个服务中的pom.xml配置。其实只比上面的配置多一句话:

<configuration>
    <protoSourceRoot>${project.basedir}/../interface/src/main/proto</protoSourceRoot>
</configuration>

这样就指定好了ProtoBuf文件所在的目录。

但其实这样还没有完。回想一下Maven的install阶段的默认行为:main/java以外的目录它不会考虑。所以,我们还需要配置额外的source路径:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>3.3.0</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>add-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>build/generated/source/proto/main/java</source>
                </sources>
            </configuration>
        </execution>
    </executions>
</plugin>

大功告成!现在就可以运行mvn compile,如果用的是IntelliJ的话你就会看到所有引用了ProtoBuf的服务的根目录下面都多了一个build文件夹,它应该是被gitignore掉的;点进去就能看到生成的桩代码,其包名就是在.proto文件里定义的包名。

接下来就是如何具体编写Java代码了!