Maven pom 继承聚合

1.1.0 简介

对于一个pom.xml来说有几个元素是必须定义的,一个是project根元素,然后就是它里面的modelVersion、groupId、artifactId和version。由上面的超级pom.xml的内容我们可以看到pom.xml中没有groupId、artifactId和version的定义,所以我们在建立自己的pom.xml的时候就需要定义这三个元素。和java里面的继承类似,子pom.xml会完全继承父pom.xml中所有的元素,而且对于相同的元素,一般子pom.xml中的会覆盖父pom.xml中的元素,但是有几个特殊的元素它们会进行合并而不是覆盖。这些特殊的元素是: dependencies,developers, contributors, plugin列表(包括plugin下面的reports), resources

1.1.1继承

1.1.1.1 被继承项目与继承项目是父子目录关系

现在假设我们有一个项目projectA,它的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/maven-v4_0_0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.tiantian.mavenTest</groupId>  <artifactId>projectA</artifactId>  <packaging>jar</packaging>  <version>1.0-SNAPSHOT</version>
</project>  

然后我们有另一个项目projectB,而且projectB是跟projectA的pom.xml文件处于同一个目录下,这时候如果projectB需要继承自projectA的话我们可以这样定义projectB的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/maven-v4_0_0.xsd">  <parent>  <groupId>com.tiantian.mavenTest</groupId>  <artifactId>projectA</artifactId>  <version>1.0-SNAPSHOT</version>  </parent>  <modelVersion>4.0.0</modelVersion>  <groupId>com.tiantian.mavenTest</groupId>  <artifactId>projectB</artifactId>  <packaging>jar</packaging>  <version>1.0-SNAPSHOT</version>
</project>  

由projectB的pom.xml文件的定义我们可以知道,当需要继承指定的一个Maven项目时,我们需要在自己的pom.xml中定义一个parent元素,在这个元素中指明需要继承项目的groupId、artifactId和version。

1.1.1.2 被继承项目与继承项目的目录结构不是父子关系

当被继承项目与继承项目的目录结构不是父子关系的时候,我们再利用上面的配置是不能实现Maven项目的继承关系的,这个时候我们就需要在子项目的pom.xml文件定义中的parent元素下再加上一个relativePath元素的定义,用以描述父项目的pom.xml文件相对于子项目的pom.xml文件的位置。

假设我们现在还是有上面两个项目,projectA和projectB,projectB还是继承自projectA,但是现在projectB不在projectA的子目录中,而是与projectA处于同一目录中。这个时候projectA和projectB的目录结构如下:

------projectA

------pom.xml

------projectB

------pom.xml

这个时候我们可以看出projectA的pom.xml相对于projectB的pom.xml的位置是“../projectA/pom.xml”,所以这个时候projectB的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/maven-v4_0_0.xsd">  <parent>  <groupId>com.tiantian.mavenTest</groupId>  <artifactId>projectA</artifactId>  <version>1.0-SNAPSHOT</version>  <relativePath>../projectA/pom.xml</relativePath>  </parent>  <modelVersion>4.0.0</modelVersion>  <groupId>com.tiantian.mavenTest</groupId>  <artifactId>projectB</artifactId>  <packaging>jar</packaging>  <version>1.0-SNAPSHOT</version>
</project>  

1.2.2聚合

对于聚合这个概念搞java的人应该都不会陌生。先来说说我对聚合和被聚合的理解,比如说如果projectA聚合到projectB,那么我们就可以说projectA是projectB的子模块, projectB是被聚合项目,也可以类似于继承那样称为父项目。对于聚合而言,这个主体应该是被聚合的项目。所以,我们需要在被聚合的项目中定义它的子模块,而不是像继承那样在子项目中定义父项目。具体做法是:

1)  修改被聚合项目的pom.xml中的packaging元素的值为pom

2)  在被聚合项目的pom.xml中的modules元素下指定它的子模块项目

对于聚合而言,当我们在被聚合的项目上使用Maven命令时,实际上这些命令都会在它的子模块项目上使用。这就是Maven中聚合的一个非常重要的作用。假设这样一种情况,你同时需要打包或者编译projectA、projectB、projectC和projectD,按照正常的逻辑我们一个一个项目去使用mvn compile或mvn package进行编译和打包,对于使用Maven而言,你还是这样使用的话是非常麻烦的。因为Maven给我们提供了聚合的功能。我们只需要再定义一个超级项目,然后在超级项目的pom.xml中定义这个几个项目都是聚合到这个超级项目的。之后我们只需要对这个超级项目进行mvn compile,它就会把那些子模块项目都进行编译。

1.2.2.1 被聚合项目和子模块项目在目录结构上是父子关系

还拿上面定义的projectA和projectB来举例子,现在假设我们需要把projectB聚合到projectA中。projectA和projectB的目录结构如下所示:

------projectA

------projectB

-----pom.xml

------pom.xml

这个时候projectA的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.tiantian.mavenTest</groupId>  <artifactId>projectA</artifactId>  <version>1.0-SNAPSHOT</version>  <packaging>pom</packaging>  <modules>  <module>projectB</module>  </modules>
</project> 

由上面的定义我们可以看到被聚合的项目的packaging类型应该为pom,而且一个项目可以有多个子模块项目。对于聚合这种情况,我们使用子模块项目的artifactId来作为module的值,表示子模块项目相对于被聚合项目的地址,在上面的示例中就表示子模块projectB是处在被聚合项目的子目录下,即与被聚合项目的pom.xml处于同一目录。这里使用的module值是子模块projectB对应的目录名projectB,而不是子模块对应的artifactId。这个时候当我们对projectA进行mvn package命令时,实际上Maven也会对projectB进行打包。

1.2.2.2被聚合项目与子模块项目在目录结构上不是父子关系

那么当被聚合项目与子模块项目在目录结构上不是父子关系的时候,我们应该怎么来进行聚合呢?还是像继承那样使用relativePath元素吗?答案是非也,具体做法是在module元素中指定以相对路径的方式指定子模块。我们来看下面一个例子。

继续使用上面的projectA和projectB,还是需要把projectB聚合到projectA,但是projectA和projectB的目录结构不再是父子关系,而是如下所示的这种关系:

------projectA

------pom.xml

------projectB

------pom.xml

这个时候projectA的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.tiantian.mavenTest</groupId>  <artifactId>projectA</artifactId>  <version>1.0-SNAPSHOT</version>  <packaging>pom</packaging>  <modules>  <module>../projectB</module>  </modules>
</project>  

注意看module的值是“../projectB”,我们知道“..”是代表当前目录的上层目录,所以它表示子模块projectB是被聚合项目projectA的pom.xml文件所在目录(即projectA)的上层目录下面的子目录,即与projectA处于同一目录层次。注意,这里的projectB对应的是projectB这个项目的目录名称,而不是它的artifactId。

6.2.2.3聚合与继承同时进行

假设有这样一种情况,有两个项目,projectA和projectB,现在我们需要projectB继承projectA,同时需要把projectB聚合到projectA。然后projectA和projectB的目录结构如下:

------projectA

------pom.xml

------projectB

------pom.xml

那么这个时候按照上面说的那样,projectA的pom.xml中需要定义它的packaging为pom,需要定义它的modules,所以projectA的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.tiantian.mavenTest</groupId>  <artifactId>projectA</artifactId>  <version>1.0-SNAPSHOT</version>  <packaging>pom</packaging>  <modules>  <module>../projectB</module>  </modules>
</project>  

而projectB是继承自projectA的,所以我们需要在projectB的pom.xml文件中新增一个parent元素,用以定义它继承的项目信息。所以projectB的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>  <parent>  <groupId>com.tiantian.mavenTest</groupId>  <artifactId>projectA</artifactId>  <version>1.0-SNAPSHOT</version>  <relativePath>../projectA/pom.xml</relativePath>  </parent>  <groupId>com.tiantian.mavenTest</groupId>  <artifactId>projectB</artifactId>  <version>1.0-SNAPSHOT</version>  <packaging>jar</packaging>
</project>  

章节小结:其实说白了,聚合和继承是非常简单的,聚合的目的是实现一键build的功能,即A进行build的时候,下面聚合了的b,c,d都会进行build构建,而继承则是父pom对插件或者依赖jar进行了表述,使得子孙可以继承这样的规范和依赖,不过在继承中,也有需要注意甚至是才坑的地方,下面我们给出实例。特别要注意在继承关系中,并不是所有的依赖和插件都会继承,一定要区别开dependency标签是默认都继承,而dependencyManagement标签下的依赖或者pluginsManagement下的插件不是默认继承,而是需要声明,没有覆盖的内容就采用父pom中的内容,但是一定要声明。

Maven之——依赖与插件管理

并不是父POM中配置的所有依赖在不同的子类中都能用到、或者用到了但是不是统一版本、为解决这个、在父POM标签中定义依赖信息、在子POM中加入依赖的引入。具体细节如下:在父POM中配置项目中使用到的依赖、但是不再是dependency标签中配置、因为此标签可以自动被继承、使用dependencyManagement标签、此标签中定义的dependency不会被子POM自动引入、必须在子类中使用dependency声明。可能有些时候会觉得直接在子POM中引用依赖不就行了?一个是统一管理、另一个是简化配置后面有提到。依赖管理两部实现:

a)在父POM中配置需要引入的依赖管理——scattered-items中的pom.xml:

<properties><junit.version>4.1</junit.version></properties><dependencyManagement><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version><scope>test</scope></dependency></dependencies></dependencyManagement>

上面使用了properties标签来定义全局变量、跟Java中定义变量意义项目、提取重复值。

b)在子POM中配置依赖——items-thkinjava中的pom.xml:

<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency>
</dependencies>

子POM中关于junit的依赖的引入只需配置groupId和artifactId就可以了、版本和scope都不用指定。

注意:关键的地方是在父POM中的dependencyManagement标签中配置的依赖是不会主动引入到子项目中的、也就是说虽然在父POM中的dependencyManagement定义了junit的依赖、假如子类中没有关于junit的<dependency>、那么子类就没有junit依赖的引入、并且假如子项目不想使用4.1版本的junit、还可以指定自己想要使用的junit版本、这样就完全覆盖了父POM中关于junit的定义、也就是说父POM中的junit定义与他无关。这样的灵活性已经够满足我们日常需求了。

建议依赖都放在父POM中的dependencyManagement、一个是减少配置、二个是方便管理、比如版本冲突就是很常见的问题。通过dependencyManagement+变量的方式统一管理、更安全高效。

依赖范围有一种是import、是只有在dependencyManagement元素下才有效果的、使用该范围的依赖通常指向一个POM、作用是将目标POM中的dependencyManagement配置导入并合并到当前POM的dependencyManagement元素中。例如想在另外一个模块中使用上面配置的dependencyManagement配置、除了复制继承之外还可以使用import范围依赖将这已配置导入:

<dependencyManagement><dependencies><dependency><groupId>org.andy.items</groupId><artifactId>scattered-items</artifactId><type>pom</type><version>1.0-SNAPSHOT</version><scope>import</scope></dependency><dependency><groupId>othergi</groupId><artifactId>otherai</artifactId><version>${other.version}</version></dependency></dependencies></dependencyManagement>

3、插件管理

插件管理与依赖管理原理一样、不同的是定义的元素标签不一样、插件管理标签是build标签的子标签pluginManagement、在父POM中定义、子POM引用。如前面有个生成源码包的插件、使用插件管理的配置过程如下:

a)父POM——scattered-items中的pom.xml:

<build><pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-source-plugin</artifactId><version>${sources.plugin.verion}</version><executions><execution><id>attach-sources</id><phase>verify</phase><goals><goal>jar-no-fork</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>1.7</source><target>1.7</target></configuration></plugin></plugins></pluginManagement></build>

b)子POM——items-thkinjava中的pom.xml:

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-source-plugin</artifactId></plugin></plugins></build>

注意的东西与依赖管理类似、只是换成了插件管理。

4、约定优于配置

标准的重要性已经不用过多强调、ConventionOver Configuration是maven最核心的设计理念之一。

任何一个maven项目都隐式的继承了超级POM、有点类似与Java所有的类都继承Object类、因此、大量超级POM的配置都会被所有maven项目继承、这些配置也就成为了maven所提倡的约定。

超级POM位置:$M2_HOME/lib/maven-model-builder-x.x.x.jar中的org/apache/maven/model/pom-4.0.0.xml路径下。

Maven pom 继承聚合相关推荐

  1. Maven 模块继承、聚合

    2019独角兽企业重金招聘Python工程师标准>>> Maven POM(项目对象模型): 通过XML配置项目的依赖,自动完成项目构建 pom.xml 标签 modelVersio ...

  2. Maven学习文档常用命令继承聚合

    学习视频 www.atguigu.com 目前的技术在开发中存在的问题 一个项目就是一个工程 如果项目非常庞大,就不适合继续使用package来划分模块.最好是每一个模块对应一 个工程,利于分工协作. ...

  3. 关于maven pom

    1 maven pom.xml只是配置文件 构建的流程已经固化在maven中了,pom.xml只是对这个流程的配置.特别是插件,在不进行人工绑定的情况下,插件是对应固定的生命周期的,我们操作的时候是操 ...

  4. maven POM.xml 标签详解

    pom作为项目对象模型.通过xml表示maven项目,使用pom.xml来实现.主要描述了项目:包括配置文件:开发者需要遵循的规则,缺陷管理系统,组织和licenses,项目的url,项目的依赖性,以 ...

  5. Maven pom.xml 全配置(二)不常用配置

    Maven pom.xml 全配置(二)不常用配置 这里贴出Maven pom.xml文件中使用率较少的配置参数,如果此篇文档中没有找到你想要的参数,移步Maven pom.xml 全配置(一)常用配 ...

  6. Maven pom.xml 全配置(一)常用配置

    Maven pom.xml 全配置(一)常用配置 这里贴出一个Maven中出现频率较高的配置参数注释,方便理解项目中Maven的配置具体的作用.如果在此博文中没有找到你想看到的参数,可以移步Maven ...

  7. 学习笔记——Maven pom.xml配置详解

    POM的全称是"ProjectObjectModel(项目对象模型)". pom.xml详解 声明规范 <projectxmlns="http://maven.ap ...

  8. 【Maven】Maven POM配置详解

    就像web项目的核心是web.xml一样,Maven项目的核心是pom.xml,POM(project object model,项目对象模型)定义了项目的基本信息,用于描述项目如何构建,如何声明依赖 ...

  9. 你真的了解Maven pom.xml 的配置吗?【详解maven pom】

    Maven POM POM( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个XML文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖 ...

最新文章

  1. private的误解
  2. java jnotify_java JNotify (基于内核)实时监控文件
  3. 中文按拼音首字母排序的C++实现方案
  4. oracle01144,ORA-01144
  5. swoole 自定义eof 标记 带返回信息(自己修改)和 不带返回信息的原本demo
  6. 微信小程序搜索关键字高亮和ctrl+f搜索定位实现
  7. Hotdog 热狗大战
  8. 任务接单平台源码自动挂机阅读文章挣钱系统
  9. eclipse查看代码git历史_Eclipse使用教程 : 利用Eclipse中git的插件来查看项目状态 - Break易站...
  10. oracle裁员原因_导致Oracle全球性裁员的原因有哪些?
  11. 微软拼音 输入法 个人 偏好设置
  12. celeste第二章_蔚蓝全剧情全流程攻略 全关卡详解图文攻略
  13. 安装红蜘蛛软件6.2教师机管理端后,无法显示学生机的解决方法
  14. 光刻厚胶 Thick Resist(SU-8 GM10xx,SU-8 Microchem,SPR220,NR26-25000P)
  15. 获取视频旋转角度,并对视频进行旋转
  16. 深夜爬虫, 我很抱歉 , 附微信 “ 网抑云” 公众号爬虫教程!
  17. 洛谷3386二分图模板
  18. CRM客户关系管理系统主要有哪些功能?
  19. linux百度云工具baidu pcs
  20. js输出数字用千分号分隔的三种方法

热门文章

  1. PoisonIvy Rat 远程溢出实战
  2. [菜鸟训练]347. 前 K 个高频元素
  3. 计算机Excel的公式计算,Excel如何自动计算天数公式?
  4. 2021网站泛目录源码系统疯狂收录超快排名放在二级目录即可
  5. 用 Python 制作家用防盗工具
  6. android修改虚拟内存(方法)
  7. 【校招内推】字节跳动2022提前批开启
  8. JAVA拾遗 — JMH与8个代码陷阱
  9. unity3d实现像素游戏的精确碰撞判定
  10. windows 平台下curl使用报错: (3) [globbing] unmatched close brace/bracket in column 13