1. 前言
Java开发过程中, 使用Maven管理依赖. 这是Maven系列文章, 主要记录<<Maven实战>>的学习过程和一些重要知识点, 以方便自己查阅.
2. 基本概述
Maven的聚合特性能够把项目的各个模块聚合在一起构建, 而继承特性则能够帮助抽取各模块相同的依赖和插件等配置, 在简化POM的同时, 还能促进各个模块配置的一致性.
3. 聚合
Maven聚合也称多模块, 能够一次构建多个模块. 聚合模块本身是一个Maven项目, 所以也有自己的POM文件, 该POM文件的packaging为pom, 并且含有modules和module元素.
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" |
这里每个module的值都是一个当前POM的相对目录, 一般而言, 为了方便快速定位内容, 模块所处的目录名称应该与其artifactId一致, 不过这不是Maven的要求.
因此, 聚合模块与其他模块的目录结构并非一定要父子关系, 通过修改module的值, 也能更改为平级关系:
1 | <module>../springboot-quickstart</module> |
Maven首先会解析聚合模块的POM, 分析要构建的模块, 并计算出一个反应堆构建顺序, 然后根据这个顺序依次构建各个模块. 反应堆包含了模块之间继承和依赖的关系. 模块间的依赖关系会将反应堆构成一个有向非循环图.
4. 继承
继承解决的是对重复依赖和插件配置的抽取. 通过定义一个父模块, 将其他模块相同的配置抽离到父模块中, 然后继承父模块, 并且父模块也是一个Maven项目, 其POM文件的packaging为pom.
子模块需要增加parent元素配置:
1 | <parent> |
relativePath定义了父模块POM文件的位置. 默认值为../pom.xml, Maven默认父POM在上一层目录下.
POM文件可被继承的元素有:
1 | groupId:项目组ID,项目坐标的核心元素 |
5. 依赖管理
子模块继承父模块时, 也会继承父模块的依赖配置, 假设添加一个util的子模块, 该模块只提供一些简单的帮助工具, 与springframework完全无关, 难道也让它依赖spring-core,spring-beans,spring-context么?这显然是不合理的.
Maven提供的dependencyManagement元素既能让子模块继承父模块的依赖配置, 又能保证子模块依赖使用的灵活性. 在dependencyManagement元素下声明的依赖不会引入实际的依赖, 不过它能够约束dependencies下的依赖使用.
在父POM使用dependencyManagement声明的依赖能够统一项目范围中依赖的版本, 在子模块使用依赖的时候就不需要版本了, 只需要简单的配置groupId和artifactId就能获得对应的依赖信息, 从而引进正确的依赖.
如果子模块不声明依赖的使用, 即使该依赖已经在父POM的dependencyManagement中声明了, 也不会产生实际的效果.
如, 在父POM定义如下dependencyManagement:
1 | <dependencyManagement> |
在子模块使用时, 只需要:
1 | <dependency> |
对于子模块而言, 可以按需添加依赖, 对于整个项目而言, 可以规范对依赖的版本号管理.
6. 参考链接
<<Maven实战>>(许晓斌)