一、概述

maven的settings.xml文件里面有proxy、server、repository、mirror的配置,在配置仓库地址的时候容易混淆

proxy是服务器不能直接访问外网时需要设置的代理服务,不常用

server是服务器要打包上传到私服时,设置私服的鉴权信息

repository是服务器下载jar包的仓库地址

mirror是用于替代仓库地址的镜像地址

下面查看源码来确定repository和mirror的优先顺序

二、初始化远程仓库

在maven的远程仓库初始化时会执行newRepositorySession方法,会创建mirror、proxy、authentication和其它系统环境信息:

this.mavenRepositorySystem.injectMirror(request.getRemoteRepositories(), request.getMirrors());
this.mavenRepositorySystem.injectProxy(session, request.getRemoteRepositories());
this.mavenRepositorySystem.injectAuthentication(session, request.getRemoteRepositories());

三、遍历注入镜像

在injectMirror方法中:

public void injectMirror(List<ArtifactRepository> repositories, List<Mirror> mirrors)
{
if ((repositories != null) && (mirrors != null)) {
for (ArtifactRepository repository : repositories)
{
Mirror mirror = getMirror(repository, mirrors);
injectMirror(repository, mirror);
}
}
}

遍历repositories,获得mirror然后注入mirror

注:这里不用担心repositories没数据,因为在之前的初始化repositories方法中会判断没有配置"central"中央仓库的时候加入默认仓库

private void injectDefaultRepositories(MavenExecutionRequest request)
throws MavenExecutionRequestPopulationException
{
Set<String> definedRepositories = this.repositorySystem.getRepoIds(request.getRemoteRepositories());
if (!definedRepositories.contains("central")) {
try
{
request.addRemoteRepository(this.repositorySystem.createDefaultRemoteRepository(request));
}
catch (Exception e)
{
throw new MavenExecutionRequestPopulationException("Cannot create default remote repository.", e);
}
}
}
public ArtifactRepository createDefaultRemoteRepository(MavenExecutionRequest request)
throws Exception
{
return createRepository("https://repo.maven.apache.org/maven2", "central", true, "daily", false, "daily", "warn");
}

三、匹配镜像

在getMirror方法中:

public static Mirror getMirror(ArtifactRepository repository, List<Mirror> mirrors)
{
String repoId = repository.getId();
if ((repoId != null) && (mirrors != null))
{
for (Mirror mirror : mirrors) {
if ((repoId.equals(mirror.getMirrorOf())) && (matchesLayout(repository, mirror))) {
return mirror;
}
}
for (Mirror mirror : mirrors) {
if ((matchPattern(repository, mirror.getMirrorOf())) && (matchesLayout(repository, mirror))) {
return mirror;
}
}
}
return null;
}

忽略不常用的layout配置,第一个循环优先寻找mirrorOf与repositoryId完全相同的mirror

第二个循环通过规则来匹配mirror,matchPattern的方法:

static boolean matchPattern(ArtifactRepository originalRepository, String pattern)
{
boolean result = false;
String originalId = originalRepository.getId();
if (("*".equals(pattern)) || (pattern.equals(originalId)))
{
result = true;
}
else
{
String[] repos = pattern.split(",");
for (String repo : repos) {
if ((repo.length() > 1) && (repo.startsWith("!")))
{
if (repo.substring(1).equals(originalId))
{
result = false;
break;
}
}
else
{
if (repo.equals(originalId))
{
result = true;
break;
}
if (("external:*".equals(repo)) && (isExternalRepo(originalRepository))) {
result = true;
} else if ("*".equals(repo)) {
result = true;
}
}
}
}
return result;
}

如果是mirrorOf是*号就匹配,如果不是就遍历可能是逗号分隔的mirrorOf值,同时看是否是!号排除的

在找到mirror后会执行injectMirror方法,把匹配的mirror注入到repository里面:

private void injectMirror(ArtifactRepository repository, Mirror mirror)
{
if (mirror != null)
{
ArtifactRepository original = createArtifactRepository(repository.getId(), repository.getUrl(), repository.getLayout(), repository
.getSnapshots(), repository.getReleases()); repository.setMirroredRepositories(Collections.singletonList(original)); repository.setId(mirror.getId());
repository.setUrl(mirror.getUrl());
if (StringUtils.isNotEmpty(mirror.getLayout())) {
repository.setLayout(getLayout(mirror.getLayout()));
}
}
}

四、总结

1、在mirrorOf与repositoryId相同的时候优先是使用mirror的地址

2、mirrorOf等于*的时候覆盖所有repository配置

3、存在多个mirror配置的时候mirrorOf等于*放到最后

4、只配置mirrorOf为central的时候可以不用配置repository

我的settings.xml一般这样设置:

<?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>X:\工具\maven资源\repository</localRepository>
<pluginGroups></pluginGroups>
<proxies></proxies>
<servers></servers>
<mirrors>
<mirror>
<id>nexus-aliyun</id>
<name>Nexus aliyun</name>
<mirrorOf>central</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/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>
<profiles></profiles>
</settings>

nexus-aliyun使用阿里云的镜像作为central中央仓库

nexus-mine作为私服,mirrorOf配置为*来提供中央仓库中不存在的jar包

maven的mirror和repository加载顺序的更多相关文章

  1. SpringBoot系列教程之Bean加载顺序之错误使用姿势辟谣

    在网上查询 Bean 的加载顺序时,看到了大量的文章中使用@Order注解的方式来控制 bean 的加载顺序,不知道写这些的博文的同学自己有没有实际的验证过,本文希望通过指出这些错误的使用姿势,让观文 ...

  2. CSS样式表、JS脚本加载顺序与SpringMVC在URL路径中传参数与SpringMVC 拦截器

    CSS样式表和JS脚本加载顺序 Css样式表文件要在<head>中先加载,这样网页显示时可以第一次就渲染出正确的布局和样式,网页就不会闪烁,或跳变 JS脚本尽可能放在<body> ...

  3. web.xml加载顺序

    一 1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个Ser ...

  4. web.xml文件加载顺序

    1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个Servl ...

  5. web.xml 中的listener、 filter、servlet 加载顺序及其详解

    在项目中总会遇到一些关于加载的优先级问题,近期也同样遇到过类似的,所以自己查找资料总结了下,下面有些是转载其他人的,毕竟人家写的不错,自己也就不重复造轮子了,只是略加点了自己的修饰. 首先可以肯定的是 ...

  6. css样式加载顺序及覆盖顺序深入理解

    注:内容转载 很多的新手朋友们对css样式加载顺序和覆盖顺序的理解有所偏差,下面用示例为大家详细的介绍下,感兴趣的朋友不要错过 { height: 100%; width: 200; position ...

  7. Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序

    直接上代码: 代码1: public class ConstroctTest { private static ConstroctTest test = new ConstroctTest(); // ...

  8. DOM加载顺序

    最近一直在困扰dom的加载顺序问题,经常会遇到以为绑定好的事件不响应等情况,一头雾水,直到请教了周围的同事,才发现了解dom的加载顺序是多么的重要. 关于这个问题,其实网上已经有一些介绍,但是我觉得并 ...

  9. PHP 依赖注入,从此不再考虑加载顺序

    说这个话题之前先讲一个比较高端的思想--'依赖倒置原则' "依赖倒置是一种软件设计思想,在传统软件中,上层代码依赖于下层代码,当下层代码有所改动时,上层代码也要相应进行改动,因此维护成本较高 ...

随机推荐

  1. Azure DevOps vsts-agent-linux 安装出错, Must not run with sudo

    在linux安装 vsts-agent-linux 在vsts-agent-linux的解压目录运行./config.sh, 提示"Must not run with sudo", ...

  2. 通过Callable接口创建线程

    通过Callable接口创建线程 一.前言 Java中创建线程的方式有四中,前两种在前面我已经详细介绍过了(Runnable和Thread),不清楚的朋友们可看这里: Java多线程之线程的启动以及J ...

  3. set和push方法压入栈顶的值获取方法

    向值栈里面放数据(储存的位置在root域里面) 向值栈放数据有多种方式,往往我们只用其中一种 1.set方法压栈 1)在Action中获取值栈对象,使用set()方法向值栈存放数据 ActionCon ...

  4. HTML(七)CSS

    一个实例 <!DOCTYPE html> 菜鸟教程(runoob.com) body { background-color:#d0e4fe; } h1 { color:orange; te ...

  5. odoo12从零开始:一、安装odoo运行环境(mac)

    写在前面: 接触odoo已经两年多了,在大学做课程设计的时候,无意间了解到odoo这个erp框架,当时的odoo在国内还默默无闻,我也不曾想过自己毕业后会从事到odoo框架的相关开发工作中来.两年多的 ...

  6. P2050 [NOI2012]美食节 动态连边优化费用流

    题意 类似的一道排队等候,算最小总等待时间的题目. 思路 但是这道题的边数很多,直接跑会tle,可以动态加边,就是先连上倒数第一次操作的边,跑一遍费用流,然后对使用了倒数第一条边的点,连上相应的倒数第 ...

  7. Codeforces Round #511 (Div. 2)-C - Enlarge GCD (素数筛)

    传送门:http://codeforces.com/contest/1047/problem/C 题意: 给定n个数,问最少要去掉几个数,使得剩下的数gcd 大于原来n个数的gcd值. 思路: 自己一 ...

  8. HDU 4396More lumber is required 过至少K条边的最短路

    /* ** 题目要求过最少k条边的最短路 */ #include <iostream> #include <cstdio> #include <cstring> # ...

  9. Pytorch读取,加载图像数据(一)

    在学习Pytorch的时候,先学会如何正确创建或者加载数据,至关重要. 有了数据,很多函数,操作的效果就变得很直观. 本文主要用其他库读取图像文件(学会这个,你就可以在之后的学习中,将一些效果直观化) ...

  10. 最小生成树问题---Prim算法学习

    一个具有n个节点的连通图的生成树是原图的最小连通子集,它包含了n个节点和n-1条边.若砍去任一条边,则生成树变为非连通图:若增加一条边,则在图中形成一条回路.本文所写的是一个带权的无向连通图中寻求各边 ...