五、聚合与继承

好久没有更新了,在这里给大家说声抱歉,实在是因为最近加班忙成狗,还有一个原因是我想把《maven实战》这本书剩下的最后几个章节看完在统一做笔记,所以......,好了闲话少许,现在开始我们今天的聚合与继承章节的知识要点回顾

study.jpg

maven的聚合特性能够把项目的各个模块都聚合在一起构建,而maven的继承特性则能够帮助抽取各个模块相同的依赖和插件等配置,从而让项目像OPPO那样从这一刻更清晰

聚合

聚合的目的是为了实现多个模块同时构建,为了配置聚合,我们需要创建独立的模块,为模块编写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.zheng</groupId>
  <artifactId>account-parent</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>parent project name</name>
  <modules>
    <module>module1-artifactId</module>
        <module>module2-artifactId</module>
  </modules>
</project>

该项目只需要提供上面的pom.xml配置文件即可,其他src也不需要,这里的packaging必须为pom,否则无法构建
为了方便构建,通常将聚合模块作为项目目录的最顶层,其他被聚合的子模块作为项目目录的子目录存在
maven在编译时会根据pom.xml中配置的modules得出一个反应堆构建顺序,并按照这个顺序编译项目模块
建议我们在创建项目的时候为项目模块提供一个合理的name,因为构建的结果中是通过各个模块中配置的name来标识每一个项目模块的构件状态的
如下所示,是对一个account-parent项目的构件结果:

image.png

继承

继承目的是为了将一些公共的配置抽取出来,方便其他模块共用,为了实现模块继承,需要以下几步:

  1. 创建一个新的项目模块,并配置其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.zheng</groupId>
  <artifactId>account-parent</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>parent project name</name>
</project>

跟聚合一样,父模块中的packaging也必须要求是pom

  1. 编写其他子模块引用父模块
<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.zheng</groupId>
    <artifactId>account-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <relativePath>../account-parent/pom.xml</relativePath>
  </parent>
  <groupId>com.zheng</groupId>
  <artifactId>account-parent</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>parent project name</name>
</project>

上面通过parent加入父模块在maven仓库中的坐标来引用maven
通过relativePath相对路径的方式指定了父模块基于当前子模块的位置,maven在构建子模块的时候就不会要求父模块一定要先于安装到本地仓库,因为通过该标签指定的相对路径已经可以明确指定到父模块,当然如果本地仓库和relativePath所提供的路径找不到父模块,那么构建将会失败

可继承的pom元素

groupId: 项目组id,项目坐标核心元素
version: 项目版本,项目坐标核心元素
description: 项目描述信息
organization: 项目组织信息
inceptionYear: 创始年份
url: 项目地址,这里可以向项目的index连接
developers: 项目开发者信息
contributors: 项目贡献者信息
distributionManagement: 项目的部署地址
issueManagement: 项目缺陷跟踪信息
ciManagement: 项目持续集成的部署信息
scm: 项目的版本控制系统信息
mailingLists: 项目的邮件地址列表信息
properties: 自定义的maven属性
dependencies: 项目依赖
dependencyMangement: 项目依赖管理配置
repositories: 项目仓库
build: 项目源码目录配置、输出目录配置、插件配置、插件管理配置等
reporting: 项目的输出目录配置、报告插件配置等
通过build参数可以看到插件配置也可以被继承

依赖管理

dependenciesdependencyManagement
在父模块pom.xml中的dependencies中引入的依赖会被所有引用该父模块的子模块继承,但并不是所有的子模块都会用到父模块中声明的依赖,所以为了防止多余的依赖,父容器中可以通过dependencyManagement来声明jar包依赖。
dependencyManagement中声明的依赖配置会被子模块继承,但是不会被实际使用,除非子模块显示通过groupId:artifactId声明需要引用该依赖
使用dependencyManagement的好处是可以在父模块中对jar包版本进行统一管理,推荐这么做

import依赖范围

在前面依赖范围提到过import,它的作用只会对pom.xml中配置的dependencyManagement有效
import的作用是:将目标pom中的dependencyManagement配置导入并合并到当前pom.xml
import依赖范围是除了使用代码复制和继承之外的又一个可以将外部配置导入的方式,下面是具体配置:
父项目b

<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.cbm.stu</groupId>
    <artifactId>maven-parent-b</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>

    <name>maven-parent-b</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.1</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.40</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

继承b的子项目

<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.cbm.stu</groupId>
    <artifactId>maven-study-mail</artifactId>
    <version>2.1</version>
    <packaging>jar</packaging>
    <name>maven-study-mail</name>
    <url>http://maven.apache.org</url>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencyManagement>
        <dependencies>
            <!-- 此处继承b 项目,type为pom,scope 为 import -->
            <dependency>
                <groupId>com.cbm.stu</groupId>
                <artifactId>maven-parent-b</artifactId>
                <version>1.0.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <!-- 从继承的父项目中继承依赖 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

import依赖范围由于其特殊性,它的类型(type)一般都是pomscopeimport

插件管理

与依赖管理相似的是插件管理,maven中提供了plugins, pluginManagement两个元素,这两个元素的用途与依赖管理中的dependenciesdependencyManagement用法一致
这里不做赘述

聚合与继承之间的关系

不同点:

  1. 聚合与继承是两个概念,其目的是完全不同的,聚合是为了解决多模块同时构建的问题,而继承则是为了解决多模块重复配置问题
  2. 对于聚合模块来说,它知道有哪些子模块需要被聚合,(<modules>),而对于继承来说它不知道有哪些子模块继承了它,但相反,子模块知道他们继承的是哪一个父模块(<parent>)
    聚合模块.png

    继承模块.png

    相同点:
    聚合与继承模块pom的类型(type)都是pom,他们都除了包含一个pom.xml文件之外,没有其他东西
    推荐做法:为了方便,可以将聚合和继承两者合成一个模块,在一个父模块中配置聚合和继承

约定优于配置

使用maven比使用ant配置更少,更方便,虽然用户感觉上自己配置的东西少了,其实是maven内部将某一些配置提前预设好了,比如在超级pom中可以看到的:

  1. 源码目录为src/main/java
  2. 编译输出目录为target/classes
  3. 打包方式为jar
  4. 包输出目录为target/
    所有项目的pom.xml都继承与超级pom中的配置,超级pom具体位置在:
    ${MVN_HOME}/lib/maven-model-builder-x.x.x.jar/org/apache/maven/model/pom-4.0.0.xml

反应堆

对于单模块反应堆就是它本身,但对于多个模块项目来说,反应堆就包含了模块之间继承与依赖的关系
maven的实际构建顺序是这样形成的:

  1. maven按序读取pom,如果该pom没有依赖模块,则直接进行构建
  2. 如果依赖了其他模块,那么先构建其他模块
  3. 递归1,2直到完成整个项目的构建工作
    特别说明,项目模块之间的依赖配置,不能出现循环依赖的现象,也就是A依赖B,B也依赖于A,这样的配置将会导致maven构建失败

裁剪反应堆

对聚合模块运行maven命令比如mvn clean installmaven会根据计算出来的反应堆顺序将全部子模块都构建完毕并安装到本地仓库,为了选择性的构件某些模块进行构建而不是将所有模块进行构建,那么可以采用maven提供的几条裁剪反应堆命令:
-am also make 构建模块同时构建所列模块依赖的其他模块
-amd also make dependency构建模块同时构建依赖当前模块的其他模块
-pl --projects 构建指定的模块,多个模块用,分隔
-rf resume-from 在计算出的反应堆顺序基础上,从指定模块开始向后构建
下面是各个命令的实例:
假设存在account-parent,account-email,account-persist三个模块,他们之间的关系如下:

模块间依赖关系.png

-pl:构建指定模块
mvn clean install -pl account-parent
将会构建account-parent模块

-am:构建模块并构建其依赖的其他模块
mvn clean install -pl account-email -am
将会构建account-parent/account-email模块

-amd: 构建模块并构建依赖它的其他模块
mvn clean install -pl account-parent -amd
将会构建account-parent/account-email/account-persist

-rf 指定构建的起始模块,假设模块依赖关系如下
account-parent
- account-email
- account-persist
mvn clean install -pl account-parent -amd -rf account-persist
将会构建account-parent/account-persist,而跳过account-email模块的构建
好了,以上就是本章的重点知识,键盘敲到这里,再看看现在的时间0:39,再想到明天台风天还要上班,赶紧洗干净滚床上睡觉啦!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 一、聚合 想要一次构建两个项目,而不是到两个模块目录下分别执行mvn命令。 为了能使用一条命令构建两个模块,需要创...
    JarvisTH阅读 610评论 0 0
  • 何为Maven的聚合 假设有这么一个场景,有ABC三个项目,需要一次构建三个项目,而不是分别到每个项目下面执行mv...
    超级大鸡腿阅读 512评论 0 0
  • Maven的聚合特性能够把项目的各个模块聚合在一起构建,而继承特性则能够帮助抽取各模块相同的依赖和插件等配置,在简...
    洛杨凡阅读 645评论 0 0
  • 那样淡然微笑的女子,一直是心里的慰籍和向往。 此心安处是吾乡。 面对迎面而来的气运加诸于身的苦楚反复,苦难侮辱,以...
    铭玥咏全阅读 175评论 0 2
  • 雨不大不小 刚刚好 不缠绵也不讨人厌烦 两条铁轨正是我生活轨迹 一头连着工作 一头连着家 旅途行人不多不少 刚刚满...
    躁动的青春阅读 234评论 0 1