Maven聚合与继承

2014/03/07 Maven

Maven集合与集成

Maven的聚合,就是用多个子模块聚合成一个整体模块,它们是整体与部分的关系,通常在定义一个整体后,再去分析这个整体的组成结构。 Maven的聚合特性能够把项目的各个模块聚合在一起构件,而Maven的继承特性能够帮助抽取各个模块相同的依赖和插件等配置,简化POM的同时,还能促进各个模块配置的一致性。

聚合

为了能使用一条命令构建两个模块A,B,需要创建一个新的模块G,然后通过模块构建整个项目的所有模块。G本身就是一个Maven项目,它必须有自己的POM,不过同时作为一个聚合项目,POM的packaging必须是pom。如下,否则无法构建。

<packaging>pom</packaging>
<modules>
    <module>modelA</module>
    <module>modelB</module>
</modules>

</modules>:实现聚合的最核心配置。用户可以通过在一个打包方式为pom的Maven项目中声明任意数量的module元素来实现模块的聚合。 一般情况,模块所处的目录名称应该与其artifactId一直。不过不是硬性要求。推荐这么做。 如何构建:Maven首先解析聚合模块的名称,不是artifactId,这是为何要在pom中配置合理的name字段。目的更好的清晰输出。 聚合使用到的元素是。对于聚合模块来说,它知道有哪些被聚合的模块,而对于被聚合的模块来说,它们不知道被谁聚合了,也不知道它的存在。所以我们要在聚合模块中添加指向被聚合模块的引用

继承

可以使用继承解决重复的配置。 可以创建一个父模块。有一个pom文件,与其他模块使用相同的groupId和version。使用artifactId为parent表示父模块。 其他模块使用继承。

可继承的POM元素如下:

  • groupId:项目组ID,项目坐标的核心元素。
  • version:项目版本,项目坐标的核心因素。
  • description:项目的描述信息。
  • organization:项目的组织信息。
  • inceptionYear:项目的创始年份。
  • url:项目的URL地址。
  • developers:项目的开发者信息。
  • contributors:项目的贡献者信息。
  • distributionManagement:项目的部署配置。
  • issueManagement:项目的缺陷跟踪系统信息。
  • ciManagement:项目的持续集成系统信息。
  • scm:项目的版本控制系统。
  • malilingLists:项目的邮件列表信息。
  • properties:自定义的Maven属性。
  • dependencies:项目的依赖配置。
  • dependencyManagement:项目的依赖管理配置。
  • repositories:项目的仓库配置。
  • build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等。
  • reporting:包括项目的报告输出目录配置、报告插件配置等。

父POM

groupId、artifactId和version指定父模块的坐标。是必须的,relativePath表示父模块POM的相应路径。Maven首先从relativePath检查父POM,如果找不到则从本地仓库查找。默认值是 . ./pom.xml 。就是说,Maven默认父POM在上一层目录下。

正确设置relativePath非常重要:如果父模块没有安装到本地仓库,relativePath路径存在问题,则找不到父POM,导致构件失败。如果根据relativePath找到父pom,它就不需要再检查本地仓库。

groupId和version也可以继承。artifactId需要自己显示声明,否则会出现坐标冲突。

依赖管理

当A,B继承W,当将A,B模块的所有依赖都写在W中的时候,现在添加C模块,但是C模块并不依赖某些构件。怎么办?

Maven提供的dependencyManagement元素,能让子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性。在dependencyManagement元素下依赖声明不会引入实际的依赖,不过它能约束dependencies下的依赖使用。

子POM中的依赖配置较原来简单了一些,所有的配置值配置了groupId和artifactId。省去了version。还可以省略范围(scope标签)。

使用这种依赖管理机制似乎不能减少太多pom配置。但是建议使用,原因:父POM使用dependencyManagement声明依赖能够统一项目范围中的依赖版本,减少多个子模块版本依赖不一致情况,降低依赖冲突。

如果子模块不声明依赖的使用,不会产生任何实际效果。

scope的import属性:导入依赖范围;只对dependencyManagement元素下才有效果,使用该范围的依赖通常指向一个POM,作用是将目标POM中的dependencyManagement配置导入到当前POM的dependencyManagement元素中。

注意:type为pom,import一般都指向打包类型为pom的模板,如果多个项目,它们使用的依赖版本都是一致的,可以定义一个dependencyManagement专门管理,各个项目导入这些依赖管理配置。

插件管理

使用pluginManagement元素管理插件。也不会造成实际的插件调用行为,当POM中配置了真正的plugin元素,并且其groupId和artifactId与pluginManagement中的配置的插件配置匹配时,pluginManagement的配置才会有实际插件行为。

聚合与继承的关系

聚合:为了方便快捷构件项目;对于聚合模块来说,它知道哪些被聚合的模块,被聚合的模块不知道这个聚合模块的存在。

继承:主要为了清除重复配置。父POM不知道哪些子模块,子模块知道父模块。

相同点:POM的packaging必须是pom。聚合模块与继承关系中的父模块除了POM之外没有实际的内容。在实际项目中,一个pom及时聚合pom又是父pom。

反应堆

反应堆(Reactor):所有模块组成一个构建结构。从而自动计算出合理的构件顺序。

反应堆顺序

Maven按序读取POM,如果POM没有依赖模块,那就构件该模块,否则先构建其依赖块,如果依赖块还依赖其他模块,则进一步先构建依赖的依赖。如果出现循环则Maven报错。

裁剪反应堆

如果用户仅仅构建反应堆中的某些个模块。 Maven提供很多的命令行选项支持裁剪反应堆。 Maven提供了很多的命令行选项支持裁剪反应堆。

  • -am 同时构建所列模块的依赖模块

  • -amd 同时构建依赖于所列模块的模块

  • -pl 构建指定的模块,模块间用都好分隔

  • -rf 从指定的模块回复反应堆

Search

    微信好友

    博士的沙漏

    Table of Contents