前言

maven有多模块和继承集中概念,还有新出来的bom。需要分开理解。

继承(parent)

继承是平日里项目主要使用的,一般定义一个主pom文件,pom中定义不同的依赖和版本。任意的子模块,都会进行一次parent模块的引用。
例如,定义父模块:

  1. <groupId>com.xxx</groupId>
  2. <artifactId>xxx-part</artifactId>
  3. <packaging>pom</packaging>
  4. <version>1.0-SNAPSHOT</version>
  5. <modules>
  6. <module>xxx-part-demo</module>
  7. </modules>
  8. <dependencyManagement>
  9. ...
  10. </dependencyManagement>

对于指定的子模块 xxx-part-demo,可以如下定义:

  1. <parent>
  2. <artifactId>xxx-part</artifactId>
  3. <groupId>com.xxx</groupId>
  4. <version>1.0-SNAPSHOT</version>
  5. <relativePath>../xxx-part</relativePath>
  6. </parent>
  7. <modelVersion>4.0.0</modelVersion>
  8. <artifactId>xxx-part-demo</artifactId>

这样我们的子模块只需要定义下 artifactId 即可,剩下的都可以从 parent pom 中获取。包括:groupId,version,url,dependencyManagement,denpendcies,repositories,build等等。

注:其中relativePath元素不是必须的,指定后会优先从指定的位置查找父pom。

父POM是为了抽取统一的配置信息和依赖版本控制,方便子POM直接引用,简化子POM的配置。

聚合(modules)

具有模块的项目被称为多模块或聚合项目。模块是此POM列出并作为一组执行的项目。通过一个pom打包的项目可以将它们列为模块来聚合成一组项目进行构建,这些模块名是这些项目的相对目录。

  1. <groupId>org.xxx</groupId>
  2. <artifactId>xxx-part</artifactId>
  3. <version>2.0</version>
  4. <packaging>pom</packaging>
  5. <modules>
  6. <module>xxx-demo</module>
  7. </modules>

其中modules不需要考虑顺序,maven会进行拓扑排序,是的依赖关系始终在依赖模块之前构建。

聚合(多模块)则是为了方便一组项目进行统一的操作而作为一个大的整体

BOM

dmavn定义的版本集合,可以解决相互兼容的jar包版本问题。不同的项目在依赖时,会发生循环依赖,各个版本不一致,而maven构件时,会采取maven dependency mediation方式,可能导致需要依赖的jar,由于上述操作被冲掉了。
BOM本质上是一个普通的POM文件,区别是对于使用方而言,里面定义好类型版本即可。

  1. <groupId>com.xxx</groupId>
  2. <artifactId>xxx-bom</artifactId>
  3. <version>1.0</version>
  4. <packaging>pom</packaging>
  5. <properties>
  6. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  7. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  8. </properties>
  9. <dependencyManagement>
  10. ...
  11. </dependencyManagement>

使用的时候,直接引入即可:

  1. <dependencyManagement>
  2. <dependencies>
  3. <dependency>
  4. <groupId>com.xxx</groupId>
  5. <artifactId>xxx-bom</artifactId>
  6. <version>${version}</version>
  7. <type>pom</type>
  8. <scope>import</scope>
  9. </dependency>
  10. </dependencies>
  11. </dependencyManagement>

如上,就引入了bom文件,后续需要任何的版本,只需要depenency直接引用就可以拿到版本信息了。需要特殊版本时,指定覆盖下。

使用

maven仅仅支持单继承,只有一个parent。对于其他项目的依赖,那么最好使用bom来实现了。

最佳路径:定义自己项目的主pom,引入各个第三方的bom文件,进行自己的开发工作。

jar传递覆盖

包版本优先级顺序如下:

  1. 当前项目 pom 直接声明的包版本
  2. parent 项目声明的包版本
  3. 导入 POM (即 BOM 项目)声明的包版本,如果有多个导入按 import 顺序解析。
  4. 依赖调解机制
    • 可以在当前项目 pom 显示指定包版本,用于覆盖依赖的包版本
    • 如果在导入的多个 BOM 项目中相同包存在多个版本,则使用声明在先的 BOM 项目中指定的包版本

参考