美文网首页Maven 学习笔记
第八章 聚合与继承

第八章 聚合与继承

作者: JarvisTH | 来源:发表于2019-05-11 20:19 被阅读0次

一、聚合

想要一次构建两个项目,而不是到两个模块目录下分别执行mvn命令。

为了能使用一条命令构建两个模块,需要创建一个额外的模块account-aggregator,然后通过该模块构建整个项目的所有模块。这个account-aggregator模块作为一个Maven项目,有自己的POM,同时作为聚合项目,又有特殊点:

<project xmlns="...">
    <modeVersion>4.0.0</modeVersion>
    <groupId>xxx.xxx.xxx</groupId>
    <artifactId>account-aggregator</artifactId>
    <version>1.1.0-snapshot</version>
    <packaging>pom</packaging>
    <name>xxx xxx</name>
    <modules>
        <module>account-email</module>
        <module>account-persist</module>
    </modules>
/project>

特殊的地方之一为packaging,值为pom。对于聚合模块来说,其打包发送packaging值必须为pom,否则无法构建。

元素modules,是实现聚合的最核心的配置。可以通过在一个打包发送为pom的Maven项目中声明容易数量的module元素来实现聚合模块。每个module的值都是一个当前POM的相对目录。

一般来说,为了方便快速定位内容,模块所处目录名称应当与其artifactId一致,不过这不是Maven的要求。

为了方便构建项目,通常将聚合模块放在项目目录的最顶层,其他模块则作为聚合模块的子目录存在。不一定要是父子关系,可以是平行目录。

如果使用平行目录结构,聚合模块的POM需要修改,指向正确的目录:

<modules>
    <module>../account-email</module>
    <module>../account-persist</module>
</modules>

聚合模块仅有一个pom.xml文件,仅仅帮助聚合其他模块构建。最后在聚合模块运行mvn clean install命令。

Maven首先解析聚合模块的POM、分析要构建的模块、计算出一个反应堆构建顺序,然后根据这个顺序依次构建各个模块。

在POM中配置合理的name字段,目的是让Maven构建输出更清晰。

二、继承

抽取重复的配置。需要创建POM的父子结构,然后在父POM中声明一些配置供子POM继承,实现“一处声明,多处使用”。

继续以上面的为基础,在account-aggregator下创建一个名为account-parent的子目录,然后在该目录下建立一个除account-aggregator之外的父模块。为此,在该子目录建一个pom.xml文件:

<project xmlns="...">
    <modelVersion>4.0.0</modulVersion>
    <groupId>xxx.xxx.xxx</groupId>
    <artifactId>acount-parent</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>
    <name>Account Parent</name>
</project>

它使用和其他模块一致的groupId和version,使用artifactId为account-parent表示父模块。packaging为pom。不包含除POM以外的文件。

父模块需要其他模块继承。修改子模块的POM:

...
<parent>
    <groupId>xxx.xxx.xxx</groupId>
    <artifactId>account-parent</artifactId>
    <version>1.0.0-snapshot</version>
    <relativePath>../account-parent/pom.xml</relativePath>
</parent>
...

使用parent元素声明父模块,parent下的groupId、artifactId和version指定父模块坐标。relativePath元素表示父模块POM的相对路径。当项目构建时,Maven会根据relativePath检查父POM,如果找不到,再从本地仓库找。默认值是../pom.xml,即默认父POM在上层目录下。

更新过的POM没有为account-email声明groupId和version,这个子模块隐式的从父模块继承了这两个元素。子类也可以显示声明该两个元素不同的值。对于artifactId元素,子模块应该显式声明。

可继承的POM元素


依赖管理

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

...
<properties>
    <springframework.version>2.5.6</springframework>
    <junit.version>4.7</junit.version>
</properties>
<dependencyManagement>
    <dependencies>
        ...
    </dependencies>
 </dependencyManagement>
...

这段配置会被继承。修改account-email的POM:

<propeties>
    ...
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
     </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
     </dependency>
     <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
     </dependency>
     <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
     </dependency>
    ...
</dependencies>

所有的springframework依赖只配置了groupId和artifactId,junit省去了version和scope。原因是继承了父pom的dependencyManagement配置。

如果子模块不声明依赖的使用,即使父POM声明了该依赖,也不会产生实际效果。

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

<dependencyManagement>
    <dependencies>
        <dependency>
            ...
            <type>pom</type>
            <scpoe>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

插件管理

提供pluginManagement元素管理插件。在该元素配置的插件不会造成实际插件调用,当pom中配置了真正的plugin元素,并且其groupId和artifactId与该元素中配置的插件匹配时,该元素配置才会影响实际插件效果。

如果子模块不需要使用父模块中pluginManagement配置的插件,可以忽略。需要配置不同插件,可以自行配置覆盖父模块配置。

四、聚合与继承关系

聚合目的是为了方便快速构建项目,继承为了消除重复配置。

聚合与继承的父模块的POM的packaging必须是pom;聚合模块和继承关系的父模块只有POM。

五、约定优于配置

约定可以大量减少配置。Maven假设目录:

  • 源码目录:src/main/java
  • 编译输出目录:target/classes/
  • 打包方式:jar
  • 包输出目录:target/

Maven允许自定义源码目录,除非特殊情况,不建议这样做。

Maven设定核心插件原因是防止由于插件版本的变化而造成构建不稳定。

六、反应堆

在一个多模块的Maven项目中,反应堆(Reactor)指所有模块组成的一个构建结构。对于单模块项目,反应堆就是本身,对于多模块项目,反应堆包含各模块间的继承和依赖关系,从而能计算出合理的模块构建顺序。

1.反应堆构建顺序

修改account-aggregator聚合配置如下:

<module>
    <module>account-email</module>
    <module>account-persist</module>
    <module>account-parent</module>
</modules>

POM的读取次序不足以决定反应堆构建顺序,要考虑模块间的依赖和继承关系。



实际的构建顺序是:Maven按序读取POM,如果该POM没有依赖模块,那么构建该模块,否则先构建其依赖模块,如果该依赖还依赖于其他模块,则进一步构建依赖的依赖。

2.裁剪反应堆

Maven提供命令行选项裁剪反应堆,mvn-h可以看到这些选项:



在-pl -am或者-pl -amd基础上,还能应用-rf参数,以对裁剪后的反应堆再次裁剪。

相关文章

  • 第八章 聚合与继承

    一、聚合 想要一次构建两个项目,而不是到两个模块目录下分别执行mvn命令。 为了能使用一条命令构建两个模块,需要创...

  • 继承与聚合

    1 问题 project 1 依赖的junit : 4.0 project 2 依赖的junit : 4.0 pr...

  • 聚合与继承

    基本概念 Maven的聚合特性能够把项目的各个模块聚合在一起构建,而Maven的继承特性则能帮助抽取各模块相同的依...

  • 聚合与继承

    Maven的聚合特性能够把项目的各个模块聚合在一起构建,而继承特性则能够帮助抽取各模块相同的依赖和插件等配置,在简...

  • Maven聚合与继承

    一、聚合 为了能够使用一条命令就能构建 account-email和 account-persist两个模块,我们...

  • 五、聚合与继承

    好久没有更新了,在这里给大家说声抱歉,实在是因为最近加班忙成狗,还有一个原因是我想把《maven实战》这本书剩下的...

  • Maven聚合与继承

    一、聚合为了能够使用一条命令就能构建 account-email和 account-persist两个模块,我们需...

  • Maven学习(四) Maven 聚合 继承 单继承

    Maven学习(四) Maven 聚合 继承 单继承 聚合 Maven聚合:一个Maven项目,用来管理它的mav...

  • 继承

    优秀文章 菜鸟教程 > Java 继承clever_fan > 重新认识java(四) — 组合、聚合与继承的爱恨...

  • Maven-继承与聚合

    1. 继承简介 1.1 继承的作用 我们知道Maven工程之间可以完成依赖的传递性,实际上就是各个jar包和war...

网友评论

    本文标题:第八章 聚合与继承

    本文链接:https://www.haomeiwen.com/subject/edcnoqtx.html