Maven实战:pom.xml与settings.xml
pom.xml与settings.xml
pom.xml与setting.xml,可以说是Maven中最重要的两个配置文件,决定了Maven的核心功能,虽然之前的文章零零碎碎有提到过pom.xml和settings.xml里面的内容,但都是大略带过,学习与研究地并不细致,本文的目的就是详细研究下这两个Maven重要的配置文件,从这两个配置文件可以牵出非常多的Maven话题。
Maven坐标
首先谈一下为什么要使用Maven坐标。
Maven世界拥有数量非常巨大的构件,也就是平时使用的一些jar、war等文件,在Maven为这些构件引入坐标概念之前,我们无法使用任何一种方式来唯一标识所有这些构件。因此,如果需要使用Spring依赖,那么就去Spring官网寻找;如果需要使用log4j依赖,那么又去Apache官网寻找。又因为各个网站风格迥异,大量时间花费在了搜索和浏览网页的工作上。没有统一规范与法则,工作就无法自动化,重复性的劳动本来就应该交给机器来做。
Maven定义了这样一组规则:世界上任何一个构件都可以使用Maven坐标唯一标识,Maven坐标元素包括groupId、artifactId、version、packaging、classifier,现在只要我们提供正确的元素坐标,Maven就能找到对应的构件。至于去哪里下载,Maven本身内置了一个中央仓库的地址”http://repo1.maven.org/maven2″,该中央仓库包含了世界上绝大部分流行的开源项目构件,Mavne会在需要的时候去那里下载,当然也可以配置自己的中央仓库地址,去自己的中央仓库下载构件。
举个例子,Spring的context:
1
2
3
4
5
|
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-context</ artifactId >
< version >4.2.6.RELEASE</ version >
</ dependency >
|
看一下下属的各个元素:
- groupId:定义当前Maven项目隶属的实际项目。由于Maven项目和实际项目未必是一对一的关系,比如SpringFramework这个实际项目可能对应的Maven项目有很多,像core、context、expression等等,因此groupId不应该对应项目隶属的公司或组织,否则artifact将很难定义
- artifactId:定义实际项目中的一个Maven模块,推荐的做法是使用实际项目名称作为artifactId的前缀,这样会很方便去寻找实际构件
- version:定义Maven项目当前所处的版本,如上面的spring-context就是4.2.6的,RELEASE表示正式发行版本
- packing:定义Maven项目的打包方式,这项不是必须的,没列出来,不定义默认就是jar的打包方式
- classifier:帮助定义构件输出的一些附属构件,比如xxx-javadoc.jar、xxx-sources.jar,附属构件与主构件对应,这项是不能直接定义的
Maven坐标的概念大致上就是这样,理解Maven坐标,是理解Maven很重要的一步。
传递性依赖
什么是传递性依赖,以Spring举一个例子。使用Spring的时候会依赖于其他开源的类库,此时有两种做法:
1、下载一个很大的.zip包,里面包含了所有Spring的jar,但是这么做往往就引入了许多不必要的依赖
2、只下载spring相关的.zip包,不包含依赖,实际使用的时候根据出错信息,加入需要的其他依赖
显然这两种做法都非常麻烦,Maven的传递性依赖机制很好地解决了这一问题。打开spring-core-4.1.0.RELEASE的pom.xml,我截取一段关键部分:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
< dependencies >
< dependency >
< groupId >commons-codec</ groupId >
< artifactId >commons-codec</ artifactId >
< version >1.9</ version >
< scope >compile</ scope >
< optional >true</ optional >
</ dependency >
< dependency >
< groupId >commons-logging</ groupId >
< artifactId >commons-logging</ artifactId >
< version >1.1.3</ version >
< scope >compile</ scope >
</ dependency >
...
</ dependencies >
|
比如A项目依赖了spring-core,spring-core又依赖了commons-codec和commons-logging,那么commons-codec和commons-logging就是A项目的一个传递性依赖。有了传递性依赖机制,在使用spring-core的时候就不用去考虑它依赖了什么,也不用担心引入多余的依赖,Maven会解析各个直接依赖的POM,将那些必要的间接依赖,以传递性依赖的形式引入到当前的项目中去。
有了传递性依赖机制,一方面大大简化和方便了依赖声明,另一方面在大部分情况下我们只需要关心项目的直接依赖是什么而不用考虑这些直接依赖会引入什么传递性依赖,不过有时候传递性依赖也会有一些问题,此时我们就需要清除地知道该传递性依赖是从哪条路径引入的,这就叫依赖调解,依赖调解主要有两点原则:
1、A->B->C->X(1.0),A->D->X(2.0),此时两条依赖路径上有两个版本的X,此时遵循路径最近者优先,因此X(2.0)将被解析使用
2、A->B->Y(1.0),A->C->Y(2.0),Y(1.0)和Y(2.0)的依赖长度是一样的,从Maven2.0.9开始,此时遵循第一声明者优先,即顺序最靠前的那个依赖优先
排除依赖
传递性依赖会给项目隐式地引入很多依赖,这极大地简化了项目依赖的管理,但是有时候这种特性也会带来问题。比如有种情况:
当前项目依赖A,A由于某些原因依赖了另外一个类库的SNAPSHOT版本,那么这个SNAPSHOT就会成为当前项目的传递性依赖,二SNAPSHOT的不稳定性将直接影响到当前的项目,此时就需要排除该SNAPSHOT,并且在当前项目中声明该类库的某个正式发布的版本
排除依赖很简单,看一下写法:
1
2
3
4
5
6
7
8
9
10
11
|
< dependency >
< groupId >com.alibaba.rocketmq</ groupId >
< artifactId >rocketmq-client</ artifactId >
< version >3.2.7</ version >
< exclusions >
< exclusion >
< groupId >apache-lang</ groupId >
< artifactId >commons-lang</ artifactId >
</ exclusion >
</ exclusions >
</ dependency >
|
这里我引入了rocketmq的依赖,但是我不想依赖rocketmq里面的apache-lang,而想要自己引入依赖,所以我就把apache-lang给排除了。
这里需要注意的是,声明exclusion的时候只需要groupId和artifactId即可,而不需要version元素,这是因为只需要groupId和artifactId就能唯一定位依赖图中的某个依赖。换句话说,Maven解析后的依赖中,不可能出现groupId和artifactId相同,但是version不同的两个依赖。
settings.xml
settings.xml里面是Maven的基本配置,元素比较多,逐一看一下
1、proxy
proxy表示Maven的代理,看一下写法:
1
2
3
4
5
6
7
8
9
10
11
12
|
< proxies >
< proxy >
< id >optional</ id >
< active >true</ active >
< protocol >http</ protocol >
< username >proxyuser</ username >
< password >proxypass</ password >
< host >proxy.host.net</ host >
< port >80</ port >
< nonProxyHosts >local.net|some.host.com</ nonProxyHosts >
</ proxy >
</ proxies >
|
需要proxy是因为很多时候你所在的公司基于安全因素考虑,要求你使用通过安全认证的代理访问因特网。这种情况下,就需要为Maven配置HTTP代理,才能让它正常访问外部仓库,以下载所需要的资源。proxies下可以配置多个proxy元素,如果声明了多个proxy元素,则默认情况下第一个被激活的proxy会生效。active为true表示激活该代理,protocol表示使用的代理协议,当然最重要的是指定正确的主机名(host)和端口(port),如果代理服务器需要认证则配置username和password,nonProxyHost元素表示指定哪些主机名不需要代理,可以用”|”分隔多个主机名,也支持通配符”*”。
2、repository
repository表示Maven的中央仓库,因为尽管默认的远程仓库中的构件非常庞大,但是总归会有不满足我们需求的时候,这时候就要用到别的中央仓库了。看一下写法:
1
2
3
4
5
6
7
8
9
10
11
|
< repository >
< id >public</ id >
< name >local private nexus</ name >
< url >http://192.168.1.6:8081/nexus/content/groups/public</ url >
< releases >
< enabled >true</ enabled >
</ releases >
< snapshots >
< enabled >false</ enabled >
</ snapshots >
</ repository >
|
可以声明多个repository。id必须是唯一的,尤其注意,Maven自带的中央仓库使用的id为central,如果其他仓库声明也用该id,就会覆盖中央仓库的配置。releases和snapshots比较重要,前者表示开启仓库的发布版本下载支持,后者表示关闭仓库的快照版本下载支持,这样一来,Maven就会去仓库下载发布版本的构件而不会下载快照版本的构件了。
3、server
大部分远程仓库无须认证就可以访问,但是有时候处于安全方面的因素考虑,需要提供认证信息才能访问一些远程仓库,处于安全考虑,认证信息一般只放在settings.xml中,server就是认证元素。看一下配置:
1
2
3
4
5
|
< server >
< id >nexus-releases</ id >
< username >deployment</ username >
< password >deployment</ password >
</ server >
|
这里的关键是id,这个id必须与需要认证的repositiry元素的id完全一致才行,换句话说,正式这个id将认证信息和仓库配置联系在了一起。
4、mirror
如果仓库X可以提供仓库Y存储的所有内容,那么就可以认为仓库X是仓库Y的一个镜像(mirror),换句话说,任何一个可以从Y中获取到的构件够可以从X中获取到。举个例子,”http://maven.net.cn/content/groups/public/”是中央仓库”http://repo1.maven.org/maven2/”在中国的镜像,由于地理位置的因素,该镜像往往能够提供比中央仓库更快的服务,这就是为什么要使用mirror的原因。
看一下mirror的配置:
1
2
3
4
5
6
|
< mirror >
< id >nexus</ id >
< name >internal nexus repository</ name >
< url >http://192.168.1.6:8081/nexus/content/groups/public</ url >
< mirrorOf >*</ mirrorOf >
</ mirror >
|
该例子中,mirrof为*,表示该配置为所有中央仓库的镜像,任何对于中央仓库的请求都会转至该镜像。另外三个元素id、name、url与一般仓库配置无异,表示该镜像仓库的唯一标识符、名称以及地址。类似的,如果该镜像需要认证,也可以基于该id配置仓库认证。
from: http://www.importnew.com/22779.html
Maven实战:pom.xml与settings.xml相关推荐
- maven配置阿里云镜像 settings.xml文件配置
在maven目录下conf文件夹下的settings.xml中添加本地仓库实际地址(可自己配置) maven默认仓库为 C:\Users\用户名\.m2\repository <localRep ...
- Maven命令行窗口指定settings.xml
maven命令行窗口指定特定settings.xml ,在命令行界面指定settings.xml,需加入如下参数: //指定使用配置xml编译项目 mvn install --settings d:\ ...
- maven配置aliyun镜像仓库settings.xml
settings.xml文件放在.m2目录下,内容如下: <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"xm ...
- maven 私服的使用及settings.xml的配置
settings中的配置 1.映射阿里中央仓库(下载jar包快一点) <mirrors><mirror><id>alimaven</id><nam ...
- 《Maven 实战》笔记之setting.xml介绍
maven是什么?有什么用? Maven是一个跨平台的项目管理工具,主要服务于Java平台的项目构建,依赖管理和项目信息管理.项目构建包括创建项目框架.清理.编译.测试.到生成报告,再到打包和部署,项 ...
- Maven实战系列文章目录
Maven实战(一)安装与配置 Maven实战(二)构建简单Maven项目 Maven实战(三)Eclipse构建Maven项目 Maven实战(四)生命周期 Maven实战(五)坐标详解 Maven ...
- Maven之pom.xml与setting.xml配置文件详解
一.Maven相关问题 安装jar到本地仓库 mvn install:install-file -Dfile=jar路径 -DgroupId=组id -DartifactId=组件id -Dversi ...
- 自定义国内maven镜像包设置settings.xml
直接复制以下代码创建一个名为settings.xml的文件,放到C:\Users\Administrator\.m2下即可 <!-- Licensed to the Apache Softwar ...
- Maven settings.xml配置详解
首先:Maven中央仓库的搜索全部公共jar包的地址是,http://search.maven.org/ ===Maven基础-默认中央仓库============================== ...
最新文章
- Java实现队列 链式存储结构
- 想实现高可用?先搞定负载均衡原理
- android-Activity
- Oracle中限定日期,Oracle 日期的一些简单使用
- ux的重要性_颜色在UX中的重要性
- brew下载的mysql卸载_Mac中mongoDB的安装与卸载步骤详解
- React开发(102):别写立即执行函数
- Python使用模块中对象的几种方法
- php写进度条原理,php实现进度条原理
- 执行环境,作用域链,闭包
- c# winForm使用Aspose.Cells读取CSV文件中文乱码问题
- 【Linux】15 张 Vim 速查表奉上,帮你提高 N 倍效率!
- 结对编程--基于android平台的黄金点游戏(2.0版本)
- struts2的ActionSupport
- 深入理解泊松分布、指数分布、正态分布
- 基于auto.js的安卓抢购软件---可实现毫秒级
- linux的进程rl,linux 进程 rl是什么状态
- mybatis中10000条数据的insert(批处理与普通方式的对比)
- 一个大牛的acm历程(看着就要颤抖)
- vs2017u5 exists, deleting.
热门文章
- php中的大括号用法
- 小白看Word2Vec的正确打开姿势|全部理解和应用
- 大数据分析:Java 下降,华为平均月薪高达 35K,分析 89 万招聘数据有这些发现!
- 中国人民银行:关于防范代币发行融资风险的公告
- java 加载中_Java 6类加载中更快的是什么?
- Redis-20Spring缓存机制整合Redis
- 学习笔记——Numpy基本操作(一)
- Redis之跳跃表(面试重点容易考)
- php是实现点击改变状态,PHP利用header函数实现各种状态的跳转
- python映射类型包括哪三种_python新手入门必备——映射类型相关函数