远程仓库的认证安全
1、通常来讲,远程仓库无须认证就能够访问maven
2、但有时候出于安全考虑,须要提供认证信息,为了防止非法的仓库访问,管理员为每一个仓库提供了一组用户名及密码工具
3、这时为了让Maven访问仓库内容,就须要配置认证信息测试
如何配置认证信息?ui
1、配置认证信息和配置仓库信息不一样,仓库信息能够直接配置在POM文件中,可是认证信息必须配置在settings.xml文件中url
2、这是由于POM每每是被提交到代码仓库中供全部成员访问的,而settings.xml通常只放在本机。所以,在settings.xml中配置认证信息更为安全spa
在settings.xml中配置仓库认证信息.net
<settings>插件
...命令行
<servers>
<server>
<id>my-proj</id>
<username>repo-user</username>
<password>repo-pwd</password>
</server>
</servers>
...
</settings>
对以上配置信息说明:
1、Maven使用settings.xml文件中并不显而易见的servers元素及其server子元素配置仓库认证信息
2、在该配置中仓库的认证用户名为repo-user,认证密码位repo-pwd
3、这里的关键是id元素,settings.xml中server元素的id必须与POM中须要认证的repository元素的id彻底一致,换句话说,正是这个id将认证信息与仓库配置联系在了一块儿
私服的一大做用之部署第三方构件
1、第三方构件包括组织内部生成的构件,以及一些没法从外部仓库直接获取的构件
2、不管是平常开发中生成的构件,仍是正式版本发布的构件,都须要部署到仓库中,供其余团队成员使用
在POM中配置构件部署地址
<project>
...
<distributionManagement>
<repository>
<id>proj-releases</id>
<name>Proj Release Repository</name>
<url>http://192.168.1.100/content/repositories/proj-releases</url>
</repository>
<snapshotRepository>
<id>proj-snapshots</id>
<name>Proj Snapshot Repository</name>
<url>http://192.168.1.100/content/repositories/proj-snapshots</url>
</snapshotRepository>
</distributionManagerment>
...
</project>
对上面的配置进行解释
1、distributionManagerment包含repository和snapshotRepository子元素,前者表示发布版本构件的仓库,后者表示快照版本的仓库
2、发布版本仓库和快照版本仓库都须要配置id、name和url
3、id为该远程仓库的惟一标识,name是为了方便人阅读,关键的url表示该仓库的地址
往远程仓库部署构件须要注意什么?
1、往远程仓库部署构件须要认证
2、在settings.xml中建立一个server元素,id与仓库的id匹配
使用mvn clean deploy
使用mvn clean deploy命令,将项目构建输出的构件部署到配置对应的远程仓库
若是项目当前的版本是快照版本,则部署到快照版本仓库地址,不然就部署到发布版本仓库地址
为何要区分发布版和快照版呢?
考虑这样一种场景,小张在开发模块A的2.1版本,该版本还未正式发布,与模块A一同开发的还有模块B,它由小张的同事季MM开发,B的功能依赖于A。在开发过程当中,小张须要常常将本身最新的构建输出,交给季MM,供她开发和测试调试,问题是,这个工做如何进行呢?
方案一:
让季MM本身签出模块A的源码进行构建。这种方法可以确保季MM获得模块A的最新构建,不过她不得不去构建模块A。多了一些版本控制和Maven操做还不算,当构件失败的时候,她会是一头雾水,最后不得不找小张解决。显然,这种方式是低效的
方案二:
重复部署模块A的2.1版本供季MM下载。虽然小张可以保证仓库中的构件是最新的,但对于Maven来讲,一样的版本和一样的坐标就意味着一样的构件。所以,若是季MM在本机的本地仓库包含了模块A的2.1版本构件,Maven就不会再对照远程仓库进行更新。除非她每次执行Maven命令以前,清除本地仓库,但这种要求手工干预的作法显然也是不可取的
方案三:
不停更新版本2.1.1、2.1.2、2.1.3 ... ... 首先,小张和季MM两人都须要频繁地更改POM,若是有更多的模块依赖于模块A,就会涉及更多的POM更改;其次,大量的版本其实仅仅包含了微小的差别,有时候是对版本号的滥用
那么如何解决上述问题?
Maven的快照版本机制就是为了解决上述问题的,在该例中,小张只须要将模块A的版本设定为2.1-SNAPSHOT,而后发布到私服中,在发布的过程当中,Maven会自动为构件打上时间戳。好比2.1-20091214.221414-13就表示2009年12月14日22点14分14秒的第13次快照。有了该时间戳,Maven就能随时找到仓库中该构件2.1-SNAPSHOT版本最新的文件,这时,季MM配置对于模块A的2.1-SNAPSHOT版本的依赖,当她构建模块B的时候,Maven会自动从仓库中检查模块A的2.1-SNAPSHOT的最新构件。当发现有更新时,便进行下载。默认状况下,Maven天天检查一次更新 (由仓库配置的updatePolicy控制),用户也可使用命令行-U参数强制让Maven检查更新,如mvn clean install -U
何时变成发布版本,为何发布版本稳定,快照版本不稳定?
当项目通过完善的测试后须要发布的时候,就应该将快照版本更改成发布版本
例如,将2.1-SNAPSHOT更改成2.1,表示该版本已经稳定,且只对应了惟一的构件,相比之下2.1-SNAPSHOT每每对应了大量的带有不一样时间戳的构件,这也决定了其不稳定性
对于快照版本的一些建议
快照版本只应该在组织内部的项目或模块间依赖使用,由于这时,组织对于这些快照版本的依赖具备彻底的理解及控制权
项目不该该依赖于任何组织外部的快照版本依赖,因为快照版本的不稳定性,这样的依赖会形成潜在的危险。也就是说,即便项目构建今天是成功的,因为外部的快照版本依赖实际对应的构件随时可能变化,项目的构建就可能因为这些外部的不受控制的因素而失败
对于快照版本的一些建议
快照版本只应该在组织内部的项目或模块间依赖使用,由于这时,组织对于这些快照版本的依赖具备彻底的理解及控制权
项目不该该依赖于任何组织外部的快照版本依赖,因为快照版本的不稳定性,这样的依赖会形成潜在的危险。也就是说,即便项目构建今天是成功的,因为外部的快照版本依赖实际对应的构件随时可能变化,项目的构建就可能因为这些外部的不受控制的因素而失败
依赖解析机制归纳
1、当依赖的范围是system的时候,Maven直接从本地文件系统解析构件
2、根据依赖坐标计算仓库路径后,尝试直接从本地仓库寻找构件,若是发现相应构件,则解析成功
3、在本地仓库不存在相应构件的状况下,若是依赖的版本是显式的发布版本构件、如1.2、2.1-beta-1d等,则遍历全部的远程仓库,发现后,下载并解析使用
4、若是依赖的版本是RELEASE或LASTEST,则基于更新策略读取全部远程仓库的元数据groupId/artifactId/maven-metadata.xml,将其与本地仓库的对应元数据合并后,计算出RELEASE或者LASTEST真实的值,而后基于这个真实的值检查本地和远程仓库
5、若是依赖的版本是SNAPSHOT,则基于更新策略读取全部远程仓库的元数据groupId/artifactId/version/maven-metadata.xml,将其与本地仓库的对应元数据合并后,获得最新快照版本的值,而后基于该值检查本地仓库,或者从远程仓库下载
6、若是最后解析获得的构件版本是时间戳格式的快照,如1.4.1-20091104.121450-121,则复制其时间戳格式的文件至非时间戳格式,如SHAPSHOT,并使用该非时间戳格式的构件
RELEASE和LASTEST版本
这两个版本分表对应了仓库中存在的该构件的最新发布版本和最新版本 (包含快照),而这两个"最新"是基于groupId/artifactId/maven-metadata.xml计算出来的
基于groupId和artifactId的maven-metadata.xml
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus</artifactId>
<versioning>
<latest>1.4.2-SNAPSHOT</latest>
<release>1.4.0</release>
<versions>
<version>1.3.5</version>
<version>1.3.6</version>
<version>1.4.0-SNAPSHOT </version>
<version>1.4.0</version>
<version>1.4.0.1-SNAPSHOT</version>
<version>1.4.1-SNAPSHOT</version>
<version>1.4.2-SNAPSHOT</version>
</versions>
<lastUpdated>20091214221557</lastUpdated>
</versioning>
</metadata>
对该配置进行解释:
1、该XML文件列出了仓库中存在的该构件全部可用的版本,同时latest元素指向了这些版本中最新的那个版本,该例中是1.4.2-SNAPSHOT
2、而release元素指向了这些版本中最新的发布版本,该例中是1.4.0,Maven经过合并多个远程仓库及本地仓库的元数据,就能计算出基于全部仓库的latest和release分别是什么,而后再解析具体的构件
在依赖声明中使用LATEST和RELEASE是不推荐的作法
由于Maven随时均可能解析到不一样的构件,可能今天LATEST是1.3.6,明天就成为1.4.0-SNAPSHOT了,且Naven不会明确告诉用户这样的变化。当这种变化形成构建失败的时候,发现问题会变得比较困难。RELEASE由于对应的是最新发布版构建,还相对可靠,LASTEST就很是不可靠了
为此,Maven 3再也不支持在插件配置中使用LATEST和RELEASE。若是不设置插件版本,其效果就和RELEASE同样,Maven只会解析最新的发布版本构件。不给过即便这样,也还存在潜在的问题,好比某个依赖的1.1版本与1.2版本可能发生一些接口的变化,从而致使当前Maven构建的失败
基于groupId、artifactId和version的maven-metadata.xml
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus</artifactId>
<version>1.4.2-SNAPSHOT</version>
<versioning>
<snapshot>
<timestap>20091214.221414</timestap>
<buildNumber>13</buildNumber>
</snapshot>
<lastUpdated>20091214221558</lastUpdated>
</versioning>
</metadata>
对该配置进行说明:
1、该XML文件的snapshot元素包含了timesstamp和buildNumber两个子元素,分别表明了这一快照的时间戳和构建号
2、基于这两个元素能够获得该仓库中此快照的最新构件版本实际为
1.4.2-20091214.221414-13,经过合并全部远程仓库和本地仓库的元数据,Maven就能知道全部参控股中该构件的最新快照
3、注意,仓库的元数据并非永远正确的,有时候当用户发现没法解析某些构件,或者解析获得错误构件的时候,就有多是出现了仓库元数据错误,这时就须要手工地,或者使用工具 (如Nexus) 对其进行修复
什么是镜像?
若是仓库X能够提供仓库Y存储的全部内容,那么就能够认为X是Y的一个镜像
换句话说,任何一个能够从仓库Y得到的构件,都可以从它的镜像中获取
举个例子,http://maven.net.cn/content/groups/public是中央仓库http://repo1.maven.org/maven2在中国的镜像,因为地理位置的因素,该镜像每每可以提供比中央仓库更快的服务
所以,能够配置Maven使用该镜像来替代中央仓库
配置中央仓库镜像settings.xml
<settings>
...
<mirrors>
<mirror>
<id>maven.net.cn</id>
<name>one of the central mirrors inChina</name>
<url>http://maven.net.cn/content/groups/public</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
...
</setting>
对上面的配置进行解释:
1、在该例中,<mirrorOf>的值为central,表示该配置为中央仓库的镜像,任何对于中央仓库的请求都会转至该镜像
2、用户也可使用一样的方法配置其余仓库的镜像
3、另外三个元素id、name、url与通常仓库配置无异,表示该镜像仓库的惟一标识符、名称以及地址。相似的,若是该镜像须要认证,也能够基于该id配置仓库认证
一个镜像的常见用法
关于镜像的一个更为常见的用法是结合私服,因为私服能够代理任何外部的公共仓库(包括中央仓库),所以,对于组织内部的Maven用户来讲,使用一个私服地址就等于使用了全部须要的外部仓库,这能够将配置集中到私服,从而简化Maven自己的配置。
配置私用私服做为镜像
<settings>
...
<mirrors>
<mirror>
<id>internal-repository </id>
<name>Internal Repository Manager</name>
<url>http://192.168.1.100/maven2</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
...
</setting>
解释上面的配置:
1、该例中<mirrorOf>的值为星号,表示该配置是全部Maven仓库的镜像,任何对于远程仓库的请求都会被转至http://192.168.1.100/maven2/,若是该镜像仓库须要认证,则配置一个id为internal-repository的<server>便可
使用很是快速的OSChina的远程仓库做为镜像替代默认的中央仓库
<settings>
...
<mirror>
<id>CN</id>
<name>OSChina Central</name>
<url>http://maven.oschina.net/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
...
</settings>
更复杂的<mirrorOf>配置
为了知足一些复杂的需求,Maven还支持更高级的镜像配置:
1、<mirrorOf>*</mirrorOf>:匹配全部远程仓库
2、<mirrorOf>external:*</mirrorOf>:匹配全部远程仓库,使用localhost的除外,使用file://协议的除外,也就是说,匹配全部不在本机上的远程仓库
3、<mirrorOf>repo1,repo2</mirrorOf>:匹配仓库repo1和repo2,使用逗号分割多个远程仓库
4、<mirrorOf>*,!repo1</mirrorOf>:匹配全部远程仓库,repo1除外,使用感叹号将仓库从匹配中排除
有一点须要注意
须要注意的是,因为镜像仓库彻底屏蔽了被镜像仓库,当镜像仓库不稳定或者中止服务的时候,Maven仍将没法访问被镜像仓库,于是将没法下载构件