maven学习系列6----聚合与继承

聚合

前面也讲过聚合的作用就是把多个模块(maven工程)放在一个模块内部,这个模块就可以说成是一个聚合,单独构建聚合模块就会把聚合在一起的其他模块一起构建(也可以配置只编译其中一部分模块)。聚合模块的packageing必须是POM,聚合模块与被聚合的模块之间的关系如下图。

对于聚合模块来说,它知道有哪些被聚合的模块,但是被聚合的模块不知道这个聚合模块的存在。

假设聚合模块名为hello,需要聚合的模块名为hello1和hello2两个模块。这里只简单说一下聚合的配置方法,不涉及项目代码。

1,目录结构

说明,这是聚合模块hello的根目录,首先是一个pom.xml配置文件,剩余的每一个目录表示一个maven工程,即需要聚合在一起的模块,如这里的hello1和hello2,其目录结构如下图所示,是一个单独的普通maven工程的目录结构

被聚合的模块放在聚合模块目录下,这个不是必须的,可以放在任何路径下,但是配置聚合模块的pom.xml时就需要配置能访问到被聚合模块的相对路径(被聚合模块相对于聚合模块的路径)了。建议放在聚合模块的根目录下,这样好管理(个人觉得这个有点违反“约定大于配置”的要求)。

2,hello/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.itsenlin</groupId>
  <artifactId>hello</artifactId>
  <strong><packaging>pom</packaging></strong>
  <version>0.0.1-SNAPSHOT</version>
  <name>hello Maven app</name>
<strong>  <modules>
    <module>hello1</module>
    <module>hello2</module>
  </modules></strong>
</project>

说明

  • hello做为聚合模块,packageing类型必须是pom
  • 需要聚合的模块名字配置在<modules/>标签下,一个<module>表示一个模块,配置的是模块的artifactId

3,hello/hello1/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.itsenlin</groupId>
  <artifactId>hello1</artifactId>
  <packaging>jar</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>hello1 Maven app</name>
  <dependencies>
    ...
  </dependencies>
  <build>
    ...
  </build>
  ....
</project>

这个没有什么需要特殊说明的,就是一个普通的maven工程的配置,hello2与hello1配置类似。

继承

也是一种maven工程,主要提取子模块的公共部分,我们称为父模块,减少子模块的重复,也可以统一子模块使用的依赖构件的版本。父模块的packageing必须是POM,父模块与子模块之间的关系如下图。

对于父模块来说,它不知道子模块的存在,而子模块中必须显示配置父模块的信息。

假设hello1和hello2模块有相同的部署需要提取,这样我们就可以创建一个hello-parent的模块当作hello1和hello2的父模块。

1,目录结构

2,hello/pom.xml

修改modules标签如下

<modules>
    <strong><module>hello-parent</module></strong>
    <module>hello1</module>
    <module>hello2</module>
  </modules>

3,hello/hello-parent/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.itsenlin</groupId>
  <artifactId>hello-parent</artifactId>
  <strong><packaging>pom</packaging></strong>
  <version>0.0.1-SNAPSHOT</version>
  <name>Parent config of helloN modules</name>
</project>

4,hello/hello1/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>
<strong>  <parent>
    <groupId>com.itsenlin</groupId>
    <artifactId>hello-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../hello-parent/pom.xml</relativePath>
  </parent></strong>

  <artifactId>hello1</artifactId>
  <packaging>jar</packaging>
  <name>hello1 Maven app</name>
  
  <dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
  </dependencies>
</project>

说明

  • hello2和hello1类似,这里不再列出hello2的pom.xml文件了
  • 在子模块中使用<parent/>标签配置父模块的信息,也即坐标信息
  • relativePath表示父模块的POM的相对位置,maven会先根据此配置的路径查找,找不到再从本地仓库中找,如果这个不配置的话需要先将父模块编译好上传到本地仓库才行。
  • 子模块可以继承groupId/version,即从一个父模块继承的子模块的groupId和version都一样,所以可以省略
  • 可继承的元素还有很多,下面再详细说明。

5,依赖管理

dependencies元素配置项目的依赖信息,这个元素也是可以被继承的,所以父工程中配置了下面的junit依赖的话,所有子工程都会依赖junit

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

但是这样配置有个缺点就是强制所有子工程都得继承此依赖关系,如果我有一个子工程中不想依赖junit的话,这种配置是搞不定的,但是很显然maven已经考虑到这种情况了,可能在父工程中在<denpendencyManagement/>标签中配置依赖信息,此依赖下的声明不会引入实际的依赖,不过它能够约束dependencies下的依赖使用(主要用于统一版本)。例如

hello/hello-parent/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.itsenlin</groupId>
  <artifactId>hello-parent</artifactId>
  <packaging>pom</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>Parent config of helloN modules</name>
<strong>  <properties>
    <junit.version>4.12</junit.version>
  </properties>
  <dependencyManagement>
      <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
      </dependencies>
  </dependencyManagement></strong>
</project>

说明

properties标签可以实现编程语言中的变量的概念,如这里的junit.version就是一个变量,值为4.12。下面直接使用${junit.version}来获取相应值

假如hello1需要依赖junit,则可以如下配置即可。

<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>
  <parent>
    <groupId>com.itsenlin</groupId>
    <artifactId>hello-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../hello-parent/pom.xml</relativePath>
  </parent>

  <artifactId>hello1</artifactId>
  <packaging>jar</packaging>
  <name>hello1 Maven app</name>
  
<strong>  <dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
    </dependency>
  </dependencies></strong>
</project>

如果hello2中如果不需要junit的依赖,则把上面配置中的粗体部署的<dependency>删除即可。

6,import依赖范围

在讲依赖范围的时候讲到maven2.0.9及以后版本引入了一个import的依赖范围。在这里才介绍是因为,这个只在dependencyManagement元素下才有效果。

使用此依赖范围的依赖通常指向一个POM类型的工程。作用是将目标POM中配置的dependencyManagement导入并合并到当前POM的dependencyManagement元素中。

例如下面配置

<dependencyManagement>
  <dependencies>
    <dependency>
        <groupId>xxxx</groupId>
        <artifactId>yyyy</artifactId>
        <version>zzzz</version>
        <strong><type>pom</type>
       <scope>import</scope></strong>
    </dependency>
  </dependencies>
</dependencyManagement>

7,插件管理

类似依赖管理

反应堆

1,概念

反应堆是指所有模块组成的一个构建结构,从模块之间的依赖与继承关系自动计算出合理的模块构建顺序。

2,构建顺序

在命令行下进入hello根目录执行mvn compile,可以看到如下打印

这个顺序并不仅是通过聚合模块的<module>的顺序来定的,而是还要考虑到模块之间的依赖及继承关系来定的。可以把hello模块中的module随意调整顺序,这个构建顺序中有依赖或继承关系的构建顺序是不变的(例如hello1与hello,hello2与hello),其他的工程以module的配置顺序。

3,裁剪反应堆

一般来说直接整个项目构建即可,但是有些场景下也有这样的需求,只构建其中的某些模块,而不是全构建。这就需要使用maven提供的选项来控制了

mvn

  • -h可以查看所有选项的信息
  • -am,--also-make 同时构建所列模块的依赖模块,常与-pl选项一起使用
  • -amd,-also-make-dependents 同时构建依赖于所列模块的的模块,常与-pl选项一起使用
  • -pl,--projects <args>  构建指定的模块,以逗号分隔多个参数
  • -rf,--resume-from <args> 从指定的模块回复反应堆

例如

mvn compile -pl hello1,hello2

E:\java_workspace\hello>mvn compile -pl hello1,hello2
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] hello2 Maven app
[INFO] hello1 Maven app
[INFO]
[INFO] ------------------------------------------------------------------------

mvn compile -pl hello1 -am

E:\java_workspace\hello>mvn compile -pl hello1 -am
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] Parent config of helloN modules
[INFO] hello1 Maven app
[INFO]
[INFO] ------------------------------------------------------------------------

mvn compile -pl hello-parent -amd

E:\java_workspace\hello>mvn compile -pl hello-parent -amd
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] Parent config of helloN modules
[INFO] hello2 Maven app
[INFO] hello1 Maven app
[INFO]
[INFO] ------------------------------------------------------------------------

上个命令的构建顺序的基础上使用-rf选项的话,可以指定从某个模块开始构建,例如从hello2开始构建,则会把parent跳过

mvn compile -pl hello-parent -amd -rf hello2

E:\java_workspace\hello>mvn compile -pl hello-parent -amd -rf hello2
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] hello2 Maven app
[INFO] hello1 Maven app
[INFO]
[INFO] ------------------------------------------------------------------------

附1,可依继承的pom元素

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

附2,参考

《maven实战》

时间: 2024-08-01 09:19:48

maven学习系列6----聚合与继承的相关文章

Maven学习总结(五)——聚合与继承

一.聚合 如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合 1.1.聚合配置代码 1 <modules> 2 <module>模块一</module> 3 <module>模块二</module> 4 <module>模块三</module> 5 </modules> 例如:对项目的Hello.HelloFriend.MakeFriends这三个模块进行聚合 1 <modules>

Maven学习总结(五)——聚合与继承【如果想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合】

一.聚合 如果我们想一次构建多个项目模块,那我们就需要对多个项目模块进行聚合 1.1.聚合配置代码 1 <modules> 2 <module>模块一</module> 3 <module>模块二</module> 4 <module>模块三</module> 5 </modules> 例如:对项目的Hello.HelloFriend.MakeFriends这三个模块进行聚合 1 <modules>

Maven学习小结(四 聚合与继承)

1.聚合 一次构建多个项目模块,将多个Maven项目合并为一个大的项目. 2.继承 为了消除重复,把很多相同的配置提取出来,例如groupid和version: 3.示例 3.1创建4个Maven项目,放在相同的目录下,其中hello_parent为父项目(聚合模块),hello_1/hello_2/hello_3为子项目(被聚合的模块):hello_parent的POM既是聚合POM,又是父POM这么做主要是为了方便. 3.1.1 hello_parent项目POM <project xmln

maven学习笔记四(聚合和继承)

聚合 现在假如,我创建了3个maven项目, user-core.2.user-log,3.user-service 这个时候,假如我们要打包这些项目,要一个一个来,会很麻烦.那么我们有没有更好的办法通过只打包一个,来让其他都打包呢?ma 这个时候,我们就可以利用maven的聚合特性来实现.新建一个空的maven项目.如下图: 创建完毕后,打开pom.xml编写如下的配置: 这个时候,我们只需要执行这一个空的maven项目即完成了所有的项目的打包. 继承 现在假如,我创建了3个maven项目,

Maven详解之聚合与继承

说到聚合与继承我们都很熟悉,maven同样也具备这样的设计原则,下面我们来看一下Maven的pom如何进行聚合与继承的配置实现. 一.为什么要聚合? 随着技术的飞速发展和各类用户对软件的要求越来越高,软件本身也变得越来越复杂,然后软件设计人员开始采用各种方式进行开发,于是就有了我们的分层架构.分模块开发,来提高代码的清晰和重用.针对于这一特性,maven也给予了相应的配置. 情景分析一: 我们在开发过程中,创建了2个以上的模块,每个模块都是一个独立的maven project,在开始的时候我们可

Maven学习系列一5分钟入门教程

Maven是基于项目对象模型的一个Apache开源项目.Maven的主要配置文件pom.xml就是项目模型的意思(Project Oriented Model),它是Apache Ant的衍生扩展. 安装 Maven是一个Java工具,所以你必须首先安装Java所需运行环境. 1.解压apache-maven-3.2.1-bin.zip到你想要安装maven的目录,例如,我解压文件到D:\apache-maven-3.2.1. 2.添加M2_HOME环境变量,(WinKey+Pause)快捷键调

Maven详解 之 聚合与继承

说到聚合与继承我们都很熟悉,maven同样也具备这样的设计原则,下面我们来看一下Maven的pom如何进行聚合与继承的配置实现. 一.为什么要聚合? 随着技术的飞速发展和各类用户对软件的要求越来越高,软件本身也变得越来越复杂,然后软件设计人员开始采用各种方式进行开发,于是就有了我们的分层架构.分模块开发,来提高代码的清晰和重用.针对于这一特性,maven也给予了相应的配置. 情景分析一: 我们在开发过程中,创建了2个以上的模块,每个模块都是一个独立的maven project,在开始的时候我们可

maven学习系列2----maven简单配置

maven几个概念 1,POM(Project Object Model,项目对象模型), 描述项目如何构建.声明项目依赖等.以xml形式来编写命名为pom.xml,一个maven项目对应一个pom.xml.相当于Ant的build.xml文件,gradle的build.gradle文件. 2,构件, 使用maven工具可以将项目编译成很多种类型的包,常用的是jar/war/pom类型的包,这些包在maven的世界中就叫构件. 3,仓库, 统一存放所有maven项目共享的构件的地方.以group

maven学习系列(一)—maven安装和基本设置

maven下载和配置 第一步:下载apache-maven-2.3.2-bin.zip并解压到D:\tools,下载地址http://maven.apache.org/download.cgi 第二步:在环境变量中设置属性:M2_HOME = D:\tools\apache-maven-3.2.3-bin\apache-maven-3.2.3 ; PATH = ;%M2_HOME%\bin; 第三步:在dos以下输入mvn -v 如显演示样例如以下,则配置成功. 第四步:自己定义本地reposi