【maven】maven settings.xml 中 mirror 和 repository 的区别

一、概述

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

  1. proxy是服务器不能直接访问外网时需要设置的代理服务,不常用
  2. server是服务器要打包上传到私服时,设置私服的鉴权信息
  3. repository是服务器下载jar包的仓库地址
  4. mirror是用于替代仓库地址的镜像地址

二、源码解析执行流程

2.1》初始化远程仓库

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

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

 2.2》遍历注入镜像

在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");
  }

2.3》匹配镜像

在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

四 、实践

4.1》maven 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">

  <pluginGroups></pluginGroups>
  <proxies></proxies>

  <servers>
      <server>
      <id>nexus-releases</id>
      <username>admin</username>
      <password>admin123</password>
    </server>
    <server>
      <id>nexus-snapshots</id>
      <username>admin</username>
      <password>admin123</password>
    </server>
  </servers>

  <mirrors> 
    <mirror> 
      <id>nexus-releases</id> 
      <mirrorOf>nexus-releases</mirrorOf> 
      <url>http://localhost:8081/nexus/content/groups/public</url> 
    </mirror>
    <mirror> 
      <id>nexus-snapshots</id> 
      <mirrorOf>nexus-snapshots</mirrorOf> 
      <url>http://localhost:8081/nexus/content/groups/public-snapshots</url> 
    </mirror> 
  </mirrors> 
 
  <profiles>
   <profile>
      <id>nexus</id>
      <repositories>
        <repository>
          <id>nexus-releases</id>
          <url>http://nexus-releases</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
        </repository>
        <repository>
          <id>nexus-snapshots</id>
          <url>http://nexus-snapshots</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
        </repository>
      </repositories>
      <pluginRepositories>
         <pluginRepository>
                <id>nexus-releases</id>
                 <url>http://nexus-releases</url>
                 <releases><enabled>true</enabled></releases>
                 <snapshots><enabled>true</enabled></snapshots>
               </pluginRepository>
               <pluginRepository>
                 <id>nexus-snapshots</id>
                  <url>http://nexus-snapshots</url>
                <releases><enabled>true</enabled></releases>
                 <snapshots><enabled>true</enabled></snapshots>
             </pluginRepository>
         </pluginRepositories>
    </profile>
  </profiles>

  <activeProfiles>
      <activeProfile>nexus</activeProfile>
  </activeProfiles>
 
</settings>

4.2》项目所在pom.xml配置

<distributionManagement>
        <!-- 两个ID必须与 setting.xml中的<server><id>nexus-releases</id></server>保持一致-->
        <repository>
            <id>nexus-releases</id>
            <name>Nexus Release Repository</name>
            <url>http://localhost:8081/nexus/content/repositories/releases</url>
        </repository>
        <snapshotRepository>
            <id>nexus-snapshots</id>
            <name>Nexus Snapshot Repository</name>
            <url>http://localhost:8081/nexus/content/repositories/snapshots</url>
        </snapshotRepository>
    </distributionManagement>

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值