【架构思考】使用 Parent POM 统一配置项目实战

在 Maven Parent POM 的使用过程中,有两个很重要的概念:Project InheritanceProject Aggregation (见参考一)。这两个技能的灵活使用,可以解决很多实际问题。

  • Project Inheritance:可以让子项目继承父项目的配置。
  • Project Aggregation:可以将多个子项目聚合起来形成一个父项目。只要 build 一次父项目,就会 trigger build 所有子项目。

话不多说,直接看实战案例:

Project Inheritance 实战1

需求:项目A,项目B,项目C中,各自引入了许多相同的依赖,比如logging,common-utils等,但是版本不尽相同。在很长的一段时间里,各自相安无事,不影响使用。但是,某一次改动中加入了新的依赖且没有恰当地测试,导致项目A在上线时发生依赖冲突而报错。

1.1

解决:我们决定对现有的所有项目的依赖版本统一管理,并且,如果以后有新的依赖改动,会执行更为严格的代码审核和测试。

总体思路:新建一个项目 dependency manager ,其中只包含 xml 配置。然后将其在本地 install ,这样其它项目就可以使用了。(或者 upload 到 nexus repository ,然后使用 Jenkins build 其它项目。)

1.2

Parent Pom

<project>
  <modelVersion>4.0.0</modelVersion>
 
  <!--define parent-->
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-parnet-pom-app</artifactId>
  <version>1.0</version>
  <packaging>pom</packaging>
 
  <!--dependency-->
  <dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
  </dependencies>
 
</project>

项目A

<project>
  <modelVersion>4.0.0</modelVersion>
 
  <!--include parent-->
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-parnet-pom-app</artifactId>
    <version>1.0</version>
  </parent>
 
  <!--module a-->
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module-a</artifactId>
  <version>1.0</version>
  
  <!--dependency-->
  <dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <!--version in parent pom-->
    </dependency>
  </dependencies>
  
</project>

Project Inheritance 实战2

需求:我的项目组内部开发了一些公用包 X,Y,Z,用于项目 A,B,C 中。但是,每次上线的时候非常麻烦,需要很多人工步骤:

  • 到项目 X 中,在 pom 文件里,去掉snapshot。例如把版本号的从 x.123-snapshot 改成 x.123。
  • 到项目 Y,Z 中重复一遍。
  • 到项目 A 中,在 pom 文件里,更新 X,Y,Z 的版本号。
  • 到项目 B,C 中重复一遍。

(注:A,B,C 的版本号去 snapshot 操作会在 Jenkins Release 时的 Web Portal 进行。)

可以想见,随着项目数量增多,操作会变得越来越复杂,也非常容易出错。

解决:将所有自己开发的项目的版本号统一管理。

思路:基于以上的例子,只需要做一点点改变。即在 child project 中不定义自己的 version 和 groupId ,而是在 parent pom 中统一定义。

2

项目A

<project>
  <modelVersion>4.0.0</modelVersion>
 
  <!--include parent-->
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-parnet-pom-app</artifactId>
    <version>1.0</version>
  </parent>
 
  <!--module a-->
  <artifactId>my-module-a</artifactId>
  <!--groupId in parent pom-->
  <!--version in parent pom-->
  
  <!--dependency-->
  <dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <!--version in parent pom-->
    </dependency>
  </dependencies>
  
</project>

Project Aggregation 实战

需求:随着时间的推移,项目D的代码量越来越多,除了其基本功能外,还加入了很多其它的小功能。因此,其文件结构非常臃肿,给后续的开发和测试带来了巨大的挑战。
解决:首先,将项目D,拆分为多个子项目D1,D2,D3。(然后,把与项目B核心功能无关的子项目单独拿出来作为一个新的项目。)

3

拆分的过程简单列举如下,不详细展开:

  • 根据业务逻辑,分析并决定要拆分成几个子模块
  • 将各个子模块的共享逻辑比如 utils 类提取出来单独放到一个模块中
  • 在做拆分前,先补全 integration test ,降低测试成本
  • 在一段时间内集中精力把功能拆分完成,且通过测试
  • 把与此同时在其它 branch 产生的 code change 合并到新模块中

母项目的 Parent Pom 如下,然后每个子项目各有自己的 Pom 文件。

<project>
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module-d</artifactId>
  <version>1.0</version>
  <packaging>pom</packaging>
 
  <modules>
    <module>my-module-d1</module>
    <module>my-module-d2</module>
    <module>my-module-d3</module>
  </modules>
</project>

参考

posted @ 2021-06-26 09:32  MaxStack  阅读(63)  评论(0编辑  收藏  举报