maven的mirror和repository加載順序


一、概述

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包

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM