写这篇文章起源于同事一个问题,大概就是进入我们公司以后,会统一发 maven 的 settings.xml 文件,直接覆盖 maven 自带的就能够正常使用。而后他想知道其中为何既要配 repository、server 还要配 mirror?这些配置属性含义是什么?这几者之间是什么关系?配了多个 repository 以后查找 jar 的前后顺序是什么?结合 mirror 又会怎么查找?php
虽然以前有把 Maven 这块做过系统的笔记(Maven 实战小结),但真的问我这块的时候,才发现遗漏了,如今补一下。html
proxy、server 很好理解,因此重点在于 repository、mirror 二者。那么如何区分二者呢?apache
这里用私服(内部仓库)和镜像(mirror)来作解释:服务器
能够看出,私服和 mirror 是两码事。前者自己是一个 repository,能够用来提供公司内部的 maven 构件;然后者自己并非 repository,它只是远程 repository 的网络加速器。网络
不过,不少 internal repository 搭建工具每每也提供 mirror 服务,好比 Nexus 就可让同一个 URL,既用做 internal repository,又使它成为全部 repository 的 mirror。maven
若是仓库X能够提供仓库Y存储的全部内容,那么就能够认为X是Y的一个镜像。换句话说,任何一个能够从仓库Y得到的构件,都胡够从它的镜像中获取。举个例子,http://maven.net.cn/content/groups/public/
是中央仓库 http://repo1.maven.org/maven2/
在中国的镜像,因为地理位置的因素,该镜像每每可以提供比中央仓库更快的速度。ide
一个 mirror 节点能够对应一个或多个 repository 节点,由 mirrorOf 中的所填的值控制。工具
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
...
<mirrors>
<mirror>
<id>planetmirror.com</id>
<name>PlanetMirror Australia</name>
<url>http://downloads.planetmirror.com/pub/maven2</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
...
</settings>
复制代码
如下是使用网易的镜像,来替代中央的仓库的配置样例:post
<mirrors>
<mirror>
<id>maven.163.com</id>
<name>maven mirror in China</name>
<url>http://mirrors.163.com/maven/repository/maven-public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
复制代码
在实际使用过程当中,会有以下的不标准配置:ui
<mirrors>
<mirror>
<id>maven.163.com</id>
<name>maven mirror in China1</name>
<url>http://mirrors.163.com/maven/repository/maven-public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<mirrors>
<mirror>
<id>aliyun.com</id>
<name>maven mirror in China2</name>
<mirrorOf>central</mirrorOf>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
复制代码
将两个不一样的镜像同时指向 central 仓库,这种方式 maven 只会选取第一个匹配的镜像,也就是 maven.163.com 这个,第二个永远不会生效。官网解释以下:
Note that there can be at most one mirror for a given repository. In other words, you cannot map a single repository to a group of mirrors that all define the same value. Maven will not aggregate the mirrors but simply picks the first match. If you want to provide a combined view of several repositories, use a repository manager instead.
当配置的是对 central 仓库的镜像时,不须要配置 repository 节点信息(由于 maven 默认已经配了)。若是须要了解的更加详细的内容,查看官网 mirror 配置介绍:guide-mirror-settings
repository 节点必须做为 repositorys 的子节点存在,而 repositorys 节点又必须做为 profiles 节点的子节点存在。
<profiles>
<profile>
<id>nexus</id>
<repositories>
<!-- 公司私服配置 -->
<repository>
<id>you-internal-repos</id>
<url>you-internal-repos-address</url>
<releases>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>warn</checksumPolicy>
</snapshots>
</repository>
<!-- 阿里云私服配置 -->
<repository>
<id>aliyun-repos</id>
<url>https://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<!-- 默认生效 -->
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
复制代码
第一点不用验证,就是 Maven 的机制。第二点是本身验证的结果,再也不累述验证过程,大概就是删除某个本地已经存在的 jar 再次打包,使用命令 mvn package -X
打包并输出详细调试日志,查找 jar 包的名字关键字,看第一次去哪一个远程仓库查,调换远程仓库定义顺序,再次尝试,便可获得结果。
如下是一个用阿里云镜像代替中央仓库的配置文件样例:
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>你的本地仓库地址</localRepository>
<pluginGroups></pluginGroups>
<proxies></proxies>
<servers></servers>
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<name>Nexus aliyun</name>
<mirrorOf>central</mirrorOf>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
<mirror>
<id>nexus-mine</id>
<name>Nexus mine</name>
<mirrorOf>*</mirrorOf>
<url>http://xx.xx.xx.xx/nexus/content/groups/public</url>
</mirror>
</mirrors>
</settings>
复制代码