Maven:聚合。

我们会想要一次构建两个项目,而不是到两个模块的目录下分别执行mvn命令。Maven聚合(或者称为多模块)这一特性就是为该需求服务的。

为了能够使用一条命令就能构建a和b两个模块,我们需要创建一个额外的名为c的模块,然后通过该模块构建整个项目的所有模块。c本身作为一个Maven项目,他必须要有自己的POM,不过,同时作为一个聚合项目,其POM又有特殊的地方。如下c的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.test</groupId>
    <artifactId>c</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>c</name>
    <modules>
        <module>a</module>
        <module>b</module>
    </modules>
</project>

上述POM依旧使用了账户注册服务共同的groupId com.test,artifactId为独立的c,版本也与其他两个模块一致,为1.0.0-SNAPSHOT.这里的第一个特殊的地方为packaging,即使用了默认值jar。对于聚合模块来说,其打包方式packaging的值必须为pom,否则就无法构建。

POM的name字段是为了给项目提供一个更容易阅读的名字。元素modules,这是实现聚合的最核心的配置。用户可以通过在一个打包方式为pom的Maven项目中声明任意数量的module元素来实现模块的聚合。这里每个module的值都是一个当前POM的相对目录,譬如该例中,c的POM的路径为D:\...\workspace\c\pom.xml,那么a就对应了目录D:\...\workspace\a\,而b对应于目录D:\...\workspace\b\。这两个目录各自包含了pom.xml、src/main/java/、src/test/java/等内容,离开c也能独自构建。

一般来说,为了方便快速定位内容,模块所处的目录名称应当与其artifactId一致,不过这不是Maven的要求,用户也可以将a项目放到d/目录下。这时,聚合的配置就需要相应的改成<module>d</module>。

为了方便用户构建项目,通常将聚合模块放在项目目录的最顶层,其他模块则作为聚合模块的子目录存在,这样当用户得到源码的时候,第一眼发现的就是聚合模块的POM,不用从多个模块中去寻找聚合模块来构建整个项目。

c的内容仅是一个pom.xml文件,他不像其他模块那样有src/main/java、src/test/java等目录。这也是容易理解的,聚合模块仅仅是帮助聚合其他模块构建的工具,他本身并无实质的内容。

关于目录结构还需要注意的是,聚合模块与其他模块的目录结构并非一定要是父子关系,例如平行的目录结构。

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

<modules>
    <module>../a</module>
    <module>../b</module>
</modules>

从聚合模块运行mvn clean install命令时,Maven会首先解析聚合模块的POM、分析要构建的模块、并计算出一个反应堆构建顺序,然后根据这个顺序依次构建各个模块。反应堆是所有模块组成的一个构建结构。

控制台输出中显示的各模块的名称,而不是artifactId,这也解释了为什么要在POM中配置合理的name字段,其目的是让Maven的构建输出更清晰。输出的最后是一个项目构建的小结报告,包括各个模块构建成功与否、花费的时间,以及整个构建花费的时间、使用的内存等。

猜你喜欢

转载自blog.csdn.net/en_joker/article/details/83856626