一、聚合

假设有两个模块:account-email和account-persist;
能够使用一条命令就能构建上述两个模块,需要创建一个额外的模块:account-aggregator;
通过account-aggregator构建整个项目的所有模块,而该模块本身也是Maven项目,有自己的Pom文件;
注意聚合模块account-aggregator打包方式packaging的值必须为pom,如下:

注意,聚合模块与其他模块的目录结构一般是父子关系,如上述pom所示。不过也不是必须的,这是要注意指向正确的模块目录(modules/module中的相对路径)。
 
此时,就可以从聚合模块运行命令进行构建各个模块,构建顺按照后面将要介绍的反应堆构建顺序进行:
  1. mvn clean install
 
二、继承
目的:抽取重复的配置,在一定程度上消除重复。
步骤:
1、在account-aggregator下创建一个目录account-parent最为父模块的目录,并在该父目录下建立pom.xml文件如下:
注意,packaging必须为pom;
另外,父模块为了消除配置的重复,因此本身不包含除POM之外的项目文件(如不需要src/main/java之类的文件夹)。
 
2、其他模块继承父模块
如在子模块account-email中的pom.xml配置如下:
注意GAV:
子模块可以继承父模块的groupId和/或version,也可以显式声明与父模块不一样的数值;
但是,artifactId必须要在子元素中显式声明,且与父模块不同。
另外,可以继承的POM元素很多,不只GAV。
 
3、把account-parent加入到聚合account-aggregator中,如下:
 
依赖管理:
Maven提供的dependencyManagement元素既能让子模块继承到父摸块的依赖配置,又能保证子模块依赖使用的灵活性。在dependencyManagement元素下的依赖声明不会引入实际的依赖,不过它能够约束dependencies下的依赖使用。例如,可以在account-parent中加入:
这里使用dependencyManagement声明的依赖既不会给account-parent引入依赖,也不会给它的子模块引入依赖不过这段配置是会被继承的,如在account-email中:
上述POM中的依赖配置较原来简单了一些,所有的springframework依赖只配置了groupId和aitifactId,省去了version,junit依赖不仅省去了version,还省去了依赖范围scope。
 
 
使用这种依赖管理机制似乎不能减少太多的POM配置,不过笔者还是强烈推荐采用这种方法。其主要原因在于在父POM中使用dependencyManagement声明依赖能够统一项目范围中依赖的版本,不会发生多个子模块使用依赖版本不一致情况,减少依赖冲突。
当然,如果子模块不声明依赖的使用,即使依赖已经在父POM的dependencyManagement中声明,也不会产生任何实际的效果。
 
插件管理:
Maven提供了dependencyManagement元素帮助管理依赖,类似地,Maven也提供了pluginManagement元素帮助管理插件。在该元素中配置的依赖不会造成实际的插件调用行为,
当POM中配置了真正的plugin元素,并且其groupld和artifactld与pluginManagement中配置的插件匹配时,pluginManagement的配置才会影响实际的插件行为。
 
三、聚合与继承的关系
多模块Maven项目中的聚合与继承其实是两个概念,其目的完全是不同的。前者主要是为了方便快速构建项目,后者主要是为了消除重复配置;
对于聚合模块来说,它知道有些被聚合的模块,但那此被聚合的模块不知道这个聚合模块的存在;
对于继承关系的父POM来说,它不知道有哪此子模块继承于它,但那些子模块都必须知道自己的父POM是什么。
实际项目中,读者会发现一个POM既是聚合POM,又是父POM,这么做主要为了方便。
 
 
四、约定优于配置
定义:Maven提倡“约定优于配置”(Convention Over Configuration)。
这不是说Maven约定的规则会忽略用户配置的规则,而是说不推荐用户配置一些规则,而是使用约定的规则。如Maven默认约定用户的项目是这样的:
当然,Maven允许自定义源码目录:
 
原因:超级POM
任何一个Maven项目都隐式地继承一个POM,就像任何JAVA类继承Object类一样,这个被继承的POM中的配置就成为Maven所提倡的约定。
Maven3中,这个超级POM文件在MAVEN_HOME/lib/maven-model-builder-x.x.x.jar中的org/apache/maven/model/pom-4.0.0.xml路径下。
例如,超级POM关于仓库的定义:
 
五、反应堆
定义:
在一个多模块的Maven项日中,反应堆( Reactor)是指所有模块组成的一个构建结构。
对于单模块的项目,反应堆就是该模块本身。但对于多模块项目来说,反应堆就包含了各模块之间继承与依赖的关系,从而能够自动计算出合理的模块构建顺序。
 
原理:
实际的构建顺序是这样形成的:Maven按序读取POM,如果该POM没有依赖模块,那么就构建该模块,否则就先构建其依赖模块。如果该依赖还依赖于其他模块,则进一步先构建依赖的依赖。
模块间的依赖关系会将反应堆构成一个有向非循环图(Directed Acyclic Graph,DAG),各个模块是该图的节点,依锁关系构成了有向边。这个图不允许出现循环,因此,当出现模块A依赖于B,而B又依赖于A的情况时,  Maven就会报错。
 
裁剪反应堆:
有时用户会想仅仅构建完整反应堆中的某些模块,即裁剪反应堆。
如:
  1. mvn clean install -pl account-email,account-persist
 
 
 
 

《Maven实战》笔记-5-pom聚合和继承的更多相关文章

  1. maven 学习笔记--仓库,聚合和继承,私服搭建

    仓库 http://blog.csdn.net/wanghantong/article/details/36427433 聚合和继承 http://www.cnblogs.com/xdp-gacl/p ...

  2. Maven学习(五)-- 聚合与继承

    标签(空格分隔): 学习笔记 Maven的聚合特性能够把项目的各个模块聚合在一起构建: Maven的继承特性能够帮助抽取各模块相同的依赖和插件等配置,在简化POM的同时,还能够促进各个模块配置的一致性 ...

  3. Maven学习笔记:POM标签大全详解

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  4. [maven] 实战笔记 - 构建、打包和安装maven

    ① 手工构建自己的maven项目 Maven 项目的核心是 pom.xml.POM (Project Object Model,项目对象模型)定义了项目的基本信息,用于描述项目如何构建,声明项目依赖等 ...

  5. [maven] 实战笔记 - maven 安装配置

    1.下载地址http://maven.apache.org/download.html 2.windows下安装maven(1)下载 apache-maven-3.0-bin.zip 解压到任意目录下 ...

  6. 【Maven实战】依赖的聚合和版本管理

    1.在之前的文章中,我们已经建立了四个Maven项目,但是此时如果我们要对这四个项目进行编译打包时,必须一个一个的进行执行命令,而聚合就是指只要我们在其中一个项目中编写一些代码,则在进行此项目的编译和 ...

  7. Java-马士兵设计模式学习笔记-代理模式-聚合与继承方式比较

    一.概述 1.目标:要在Tank的move()方法做时间代理及日志代理(可以设想以后还要增加很多代理处理),且代理间的顺序可活更换 2.思路: (1)聚合:代理类聚合了被代理类,且代理类及被代理类都实 ...

  8. 你分得清楚Maven的聚合和继承吗?

    用了 Maven 好几年了,许多人还是只懂得简单的依赖坐标.对于 Maven 的聚合和继承还是一知半解,甚至很多人以为是同一个东西.但其实聚合是用于快速构建项目,是表示项目与子项目之间的关系.而继承则 ...

  9. 【maven】---聚合和继承

    前言 自从我知道写maven实战这本书的作者长得随心所欲后,我再拿起这本书真心的不想看前言了.下面分享一下maven中的所谓的聚合和继承. 内容 下文中的子本指的是:多个maven项目. 父本指的是: ...

随机推荐

  1. vue.js初学(三)模板语法

    1:介绍 vue.js允许开发者声明式地将Dom元素绑定至Vue实例的底层,所有的模板都是合法的html,所以能够被遵循规范的浏览器和html解析器解析 在底层的实现上,vue将模板编译成虚拟Dom渲 ...

  2. PHP怎么把经过UTF-8编码的中文字符转换成正常的中文

    问题的场景: html 为utf-8编码<meta http-equiv="Content-Type" content="text/html; charset=UT ...

  3. Azure Managed Disk操作

    Azure Managed Disk对原有的Page Blob进行了一次封装.使得Azure VM的Disk操作变得非常简单.本文将介绍实际操作中针对Manage Disk的一些操作. 一.创建Man ...

  4. Angular5学习笔记 - 配置Http(七)

    一.引入Http模块 编辑\src\app\app.module.ts文件 import { HttpModule } from '@angular/http'; /* 注册模块 */ imports ...

  5. 编译PHP扩展的通用方法

    以安装swoole扩展为例: 步骤1: wget  pecl.php.net/get/swoole-1.7.21.tgz  (下载swoole打包文件) 步骤2: tar zxvf swoole-1. ...

  6. Scala的Json序列化

    import java.util.TimeZone import com.fasterxml.jackson.databind.{DeserializationFeature, ObjectMappe ...

  7. python的ftp上传和下载

    # -*- coding: utf- -*- import os import ftplib USER_NAME = "" PASSWORD = "" SERV ...

  8. c# 实用精华知识点全解

    本文介绍c#的实用知识点 写在前面(通识) vs常用快捷键 F5 调试运行程序 ctrl F5 不调试运行程序 F11 逐条语句调试 F10 逐过程调试程序 注释快捷键 ctrl + k + c 代码 ...

  9. _tprintf(), printf(),wprintf() 与控制字符 %s 和 %S(Unicoe与GB2312))

    _tprintf() 是 printf() 和 wprintf() 的通用类型:如果定义了 _unicode,那么 _tprintf() 就会转换为 wprintf(),否则为 printf() . ...

  10. 服务器启动时Webapp的web.xml中配置的加载顺序

    一 1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个Ser ...