【Maven】setting.xml中mirror和repository的关系


在配置Maven的setting.xml文件时,里面会有mirror元素和repository元素,前者时镜像配置,后者是库的配置。

什么是镜像,简明扼要的说,如果Y库中的所有东西,都能从X库中得到,那么X就是Y的镜像。

如图:


配置了mirror的话,就会从B中获取资源,而如果没有配置mirror,用户只能从A中获取获取资源,而如果用户此时对A的网络情况不太好,那么下载资源的速度会很慢,影响开发效率。这个时候,mirror更像是一个拦截器的存在,把对A的请求全部拦截发往B。

我们可以从Maven的源代码中窥探一下这两者的关系:

@Deprecated  
public ArtifactRepository getMirrorRepository(ArtifactRepository repository) {  
    Mirror mirror = mirrorSelector.getMirror(repository, legacySupport.getSession().getSettings().getMirrors());  
    if (mirror != null) {  
        String id = mirror.getId();  
        if (id == null) {  
            // TODO: this should be illegal in settings.xml  
            id = repository.getId();  
        }  
        log.debug("Using mirror: " + mirror.getUrl() + " (id: " + id + ")");  
        repository = artifactRepositoryFactory.createArtifactRepository(id, mirror.getUrl(),  
                repository.getLayout(), repository.getSnapshots(),  
                repository.getReleases());  
    }  
    return repository;  
}
public 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;  
} 
从上面这两段代码中可以看出,

1.它会根据repository去寻找对应的mirror,如果没有找到,则直接返回使用这个repository的配置,如果找到了,则通过createArtifactRepository方法使用这个mirror中的url新构造一个repository,来请求资源。

在两个for循环中,分别是对mirror和repository的匹配,

第一种情况是针对单个id的匹配,mirror中mirrorOf的值等于repository的id,并且layout匹配(通常情况下layout是默认的,不会进行特殊配置),mirrorOf这个元素的意思很明显,字面意思就是指谁的mirror,也就是对谁的镜像,当mirrorOf的值和repository的id匹配时,那么就使用这个mirror。

第二种情况是针对范围的匹配,先看看matchPattern函数的内容:

static boolean matchPattern(ArtifactRepository originalRepository, String pattern) {  
    boolean result = false;  
    String originalId = originalRepository.getId();  
    //首先匹配*号,如果mirrorOf是*号,就用当前的镜像  
    //或者如果当前的mirrorOf和repository的id一样也返回(这在前面的for循环处理过,所以这种情况基本不会出现)  
    if (WILDCARD.equals(pattern) || pattern.equals(originalId)) {  
        result = true;  
    } else {  
        //其次mirrorOf支持多个用逗号隔开,这里先拆分,逐个循环  
        String[] repos = pattern.split(",");  
        for (String repo : repos) {  
            //repo支持!(感叹号)来屏蔽一个repository的Id,这里先判断如果是排除的,就return false  
            if (repo.length() > 1 && repo.startsWith("!")) {  
                if (repo.substring(1).equals(originalId)) {  
                    // explicitly exclude. Set result and stop processing.  
                    result = false;  
                    break;  
                }  
            }  
            //逗号隔开中的一个值和repository的id一样就返回true  
            else if (repo.equals(originalId)) {  
                result = true;  
                break;  
            }  
            //检查外部匹配external:*  
            else if (EXTERNAL_WILDCARD.equals(repo) && isExternalRepo(originalRepository)) {  
                result = true;  
            }  
            //最后检查*匹配  
            else if (WILDCARD.equals(repo)) {  
                result = true;  
            }  
        }  
    }  
    return result;  
}  
系统中定义了一个全匹配*和外部全匹配external:*
private static final String WILDCARD = "*";  
private static final String EXTERNAL_WILDCARD = "external:*";  
从这段代码可以得到如下规则:

2.如果mirrorOf是*(星号通配符)或者和repository的id一样就使用该mirror

3.对于mirrorOf多个或一个的情况,从第一个开始判断

3.1如果是一个排除选项,就不使用这个mirror

3.2如果正好和repository的id一样就使用这个mirror

3.3判断是否外部匹配(这里还有一个isExternalRepo方法,判断是否为本地库),如果不是本地仓库,就用该mirror

3.4判断是否为*(星号),如果是,就用该镜像。

mirror的寻找中,首先会从settings配置的第一个mirror开始循环,其次从mirrorOf逗号隔开的内容循环。



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值