Maven POM文件介绍
本文链接: https://www.cnblogs.com/hchengmx/p/15085639.html
1. POM文件是什么
pom是 Project Object Module(项目对象模型)的缩写,是Maven中的项目文件。这个文件很多 默认值。
从官方网站 参考,目前Maven最新版本为 3.8.1
1.1 Super POM
Super POM 是一个特殊的POM文件,也是 Maven默认的 POM。
要是不指定的话,所有的 POM 都是继承于 Super POM,要是修改了 setting.xml文件,就会 读取xml文件中的配置。
这个POM文件可以在 [Maven Super Pom](Maven Model Builder – Super POM) 找到。
也可以在 本地这个路径找到 $MAVEN_HOME/lib/maven-model-builder-3.8.1.jar!/org/apache/maven/model/pom-4.0.0.xml
。
注:必须解压 maven-model-builder-3.8.1.jar 这个文件后,才可以得到得到进一步的路径。
以3.8.1 为例,Super POM 里面主要定义了一些基本的配置,
1. repositories
定义了一个名叫 central的repository,value是 'https://repo.maven.apache.org/maven2',可以从这个地址拉下来dependency。
2. pluginRepositories
默认 plugin的 repositories
3. build
设置了一些默认的路径,其中还定义了 几个插件,不过Maven官方也提醒,未来的版本会去掉。
<pluginManagement>
<!-- NOTE: These plugins will be removed from future versions of the super POM -->
<!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
.....
</pluginManagement>
1.2 Minimal POM
对于一个POM来说,至少需要以下几个标签
project
:rootmodelVersion
: 4.0.0groupId
: project所在组artifactId
: artifact(project)的idversion
: artifact的版本
e.g.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</project>
注:groupId + artifactId + version 需要时唯一的。在仓库中的名字为 com.mycompany.app:my-app:1
运行 mvn package
就可以得到一个 JAR文件。
1.3 Effective POM
mvn help:effective-pom
会在控制台中输出,相当于 super pom + 当前项目的 pom。
3. 项目继承 和 项目聚合
2.1 Project Inheritance 项目继承
上例提到Super POM是一种特殊的 项目继承。同时,你也可以 自定义 你的项目要继承于哪个。
Example 1
在之前的例子中,提到了 com.mycompany.app:my-app:1,假如我们又引入了另外一个项目 com.mycompany.app:my-module:1
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
想要 my-module继承于 my-app,my-module就可以用以下的POM文件
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-module</artifactId>
<version>1</version>
</project>
在这里引入了 ,这个标签就指明了说,我们当前的project的 parent是哪个。这样我们的项目就可以用 parent POM的一些东西了。
btw: 你项目的groupId 或者 version 要是和 parent的相同的话,你可以删除掉两行,看起来简练一点。
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
</parent>
<artifactId>my-module</artifactId>
</project>
2.2 Project Aggregation 项目聚合
跟 Project Inheritance 类似,但是 Project Inheritance是在 子项目中 指明 父项目 是谁? Project Aggregation 是在父项目中,指代子项目都有谁
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<module>my-app-service-api</module>
<module>my-app-infrastructure</module>
<module>my-app-service</module>
<module>my-app-start</module>
</project>
2.3 总结
要是有很多Maven projects,他们都拥有相似的 配置,就建议把 相似的配置提出来,放到 parent project里面。
要是有一些project,他们互相依赖,那就建议 用 Module的形式。
3. Dependency
3.1 Dependency Scope
在引用 dependency的时候,scope有两个作用,1 限制dependency的传递;2. 标明这个dependency 在何时有效。
比如
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
compile
默认的scope。compile dependency在 项目的整个生命周期中都适用,同样,也会传递到依赖的项目中。
provided
跟compile相似,但是标明dependency 由 jdk或者容器提供,比如 Servlet AP 和 Java EE APIS,没有传递性。
runtime
编译的时候不用,执行的时需要,比如 JDBC。
test
只用于测试中,不用于运行时。比如 JUnit \ Mockito。
system
跟 provided相似,但是在系统中要以外部包的形式提供,maven不会在repository中查找它。所有它必须要有一个 systemPath
的标签
<dependencies>
<dependency>
<groupId>javax.sql</groupId>
<artifactId>jdbc-stdext</artifactId>
<version>2.0</version>
<scope>system</scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>
</dependencies>
import
import只适用于 里面,它是为了解决 maven只支持单继承的问题。比如公司有自己的项目,所以parent必须是公司的项目,但是又想继承于 spring boot,就可以用以下这种写法,标明将 spring-boot-dependencies
中的 dependencyManagement
的 dependencies,全部引入当前工程的 dependencyManagement
。
3.2 Transitive Dependencies 传递依赖
举个例子,要是 project A
依赖于 Project B
,Project B
又依赖于 project C
,那么就有了依赖传递,这个时候 project A
依赖于 project C
A
├── B
│ └── C
那这个时候就有个问题,dependency scope是怎么传递的呢? 比如 上例中,引用Project B
的scope是 test,引用Project C
的时候是 compile的,那A引用C的时候是什么 scope的呢?
就可以参考下面的对照关系,列是就是上例中的 project A
引用 project B
的 scope,行就是上例中的 project B
引用 Project C
的scope ,要是没有值的话,就代表这个dependency会被忽略掉。
compile | provided | runtime | test | |
---|---|---|---|---|
compile | compile | - | runtime | - |
provided | provided | - | provided | - |
runtime | runtime | - | runtime | - |
test | test | - | test | - |
3.2.1 Optional dependencies
含义:可以主动不把 可以传递的依赖 传递下去。
例子:如果 B 引用 了C,并且把 Z表明为 Optional。
那么当 A 引用 B的时候,A就只会引用 B,不会引用 C,即使B和C的scope都是 compile。
<dependencies>
<!-- declare the dependency to be set as optional -->
<dependency>
<groupId>sample.ProjectC</groupId>
<artifactId>Project-C</artifactId>
<version>1.0</version>
<scope>compile</scope>
<optional>true</optional> <!-- value will be true or false only -->
</dependency>
</dependencies>
3.2.2 Excluded denpendencies
如果 X 引用了Y,Y引用了Z,但是X又不想引用Z,就可以在引用Y的时候,Excluded Z。
3.2.3 Nearest Definition 最短路径原则
Example
A
├── B
│ └── C
│ └── D 2.0
└── E
└── D 1.0
在以上的例子中,对于引用D有两种路径 A -> B -> C -> D 2.0 或者 A -> E -> D 1.0,Maven认为 AED 比 ABCD 短,所以实际引用D的版本号为 1.0。
Example
在以上的例子中,要是我们确实想引用 D2.0的话,就可以再加上一个dependency,把整个项目的引用关系变为如下
A
├── B
│ └── C
│ └── D 2.0
├── E
│ └── D 1.0
│
└── D 2.0
此时 A -> D 2.0就变成最短的了。
注:要是路径长度长度相同,就选择第一个出现的版本。
3.3 dependencyManagement
这样的好处是:子项目无需再指定dependency的版本号,子项目的dependency的所有版本号 由 parent统一管理。
用以下这个POM引用举例子
A
├── B
│ └── C
│ └── D
└── E
└── D
假如有一天,D升级了版本,这个时候需要做的事情是 C 和 E都需要更新升级版本,C升级的话,B也要升级,最终A也要被动升级版本。这样会遇到一个问题,子项目升级版本以后,需要父项目被动的升级版本,项目多的话很可能就传输信息错误了。那么能不能所有的版本管理,由父项目统一管理呢,每次版本更新,只需要更新父项目,变成主动的更新。
所以对于上面的例子,A项目就可以维护一个 的 section,维护B、C、D、E的版本号。这样 B、C、D、E被引用的时候就不用声明版本号了。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.my-app</groupId>
<artifactId>project-b</artifactId>
<version>${project.b.version}</version>
</dependency>
<dependency>
<groupId>com.my-app</groupId>
<artifactId>project-c</artifactId>
<version>${project.c.version}</version>
</dependency>
......
</dependencies>
</dependencyManagement>
假如 C引用D的时候,没有版本号,此时
MAVEN的逻辑是:
- 要是指定了 Version,那就取指定 Version的dependency。
- 要是没有指定 Version,就去parent里面的 tag下找,有无这个dependency的声明,有的话取这个版本的 dependency,没有的话报错。
参考链接
1. Maven - Ref links
2. maven/pom-4.0.0.xml · apache/maven
3. Maven – Introduction to the POM
4. Maven – POM Reference
5. Maven: The Complete Reference - The Nexus
Maven POM文件介绍的更多相关文章
- scala maven pom文件
老司机的spark maven pom文件 pom文件一: 4.0.0 <groupId>com.glsx</groupId> <artifactId>spark- ...
- maven pom文件简单模板和配置详解
https://blog.csdn.net/earbao/article/details/49924943 maven pom文件简单模板和配置详解
- Hadoop Maven pom文件示例
Hadoop Maven pom文件示例 @(Hadoop) <?xml version="1.0" encoding="UTF-8"?> < ...
- 【maven】maven pom文件详解
maven pom文件详解 最近配置maven中的pom文件,maven中有些属性不太清楚,在这里记录一下 <project xmlns="http://maven.apache.or ...
- maven pom文件详解
http://www.blogjava.net/hellxoul/archive/2013/05/16/399345.html http://blog.csdn.net/houpengfei111/a ...
- Maven pom文件常用配置,转载
什么是POM Project Object Model,项目对象模型.通过xml格式保存的pom.xml文件.作用类似ant的build.xml文件,功能更强大.该文件用于管理:源代码.配置文件.开发 ...
- maven pom文件
setting.xml主要用于配置maven的运行环境等一系列通用的属性,是全局级别的配置文件:而pom.xml主要描述了项目的maven坐标,依赖关系,开发者需要遵循的规则,缺陷管理系统,组织和li ...
- maven pom文件报错:Multiple annotations found at this line 解决方案(转)
研究maven多模块项目时,因为家里和公司不能同时开发,所以把家里搭建好的项目复制到公司继续研究, 当时家里的电脑搭建好项目之后是没问题的,但是复制到公司的eclipse上之后就看到pom文件出现下面 ...
- 史上最全的Maven Pom文件标签详解
<span style="padding:0px; margin:0px"><project xmlns="http://maven.apache.or ...
随机推荐
- [源码解析] TensorFlow 之 分布式变量
[源码解析] TensorFlow 之 分布式变量 目录 [源码解析] TensorFlow 之 分布式变量 1. MirroredVariable 1.1 定义 1.2 相关类 1.2.1 类体系 ...
- python中一些列表知识
列表 序列是 Python 中最基本的数据结构. 序列中的每个值都有对应的位置值,称之为索引,第一个索引是 0,第二个索引是 1,依此类推. Python 有 6 个序列的内置类型,但最常见的是列表和 ...
- Python多线程Threading爬取图片,保存本地,openpyxl批量插入图片到Excel表中
之前用过openpyxl库保存数据到Excel文件写入不了,换用xlsxwriter 批量插入图片到Excel表中 1 import os 2 import requests 3 import re ...
- PicLite 开发日志 v0.0.2
PicLite 开发日志 (v0.0.2) 感谢您阅读本片文章! Gitee 地址:https://gitee.com/XiaoQuQuSD/pic-lite. 新增功能 添加复制 url 的格式选项 ...
- 攻防世界-MISC:pure_color
这是攻防世界高手进阶区的第六题,题目如下: 点击下载附件一,得到一张空白的png图片 用StegSolve打开,然后点击箭头(如下图所示) 多点击几次,即可得到flag 所以,这道题的flag如下: ...
- SpringMVC 配置 & 初识 & 注解 &重定向与转发
初识 在web.xml 中注册DispatcherServlet <servlet> <servlet-name>springmvc</servlet-name> ...
- 单列集合(Collection-Set)
(部分) Set类特点: "无序"(输入顺序和存储顺序不一样) HashSet 底层是HashMap 关于不能有重复元素/对象 遇到的问题: 解决办法:重新类的相关方法 选择名字和 ...
- javaScript中Number数字类型方法入门
前言 Number和Math都属于JavaScript中的内置对象,Number数字类型作为基础数据类型,我们在开发过程中会经常用到,包括数字精度的格式化,还有字符串转换成数字等操作. Number数 ...
- Linux Centos7 根分区磁盘扩容[详解]
CentOS7 根分区扩容 [详细过程] 前提 1.如果原来的系统根分区为逻辑卷分区 则可以使用如下的方法 如果不是则不可以 2.如果原来的系统根分区不是逻辑卷分区 则不可以扩展只能再添加挂在磁盘进行 ...
- 1.9 初学者应选择哪个Linux发行版?
前面章节中,已经对几个常见的 Linux 发行版做了简单的介绍,那么对于初学者来说,选择哪个发行版的性价比更高呢? 通常情况下,初学者学习 Linux,是为了找一份和 Linux 相关的工作,那么问题 ...