• 零、前言
  • 一、Maven设置远程仓库
  • 二、测试使用到的settings.xml和pom.xml
  • 1. settings.xml
  • 2. pom.xml
  • 三、测试
  • 测试一:
  • 测试二:
  • 测试三:
  • 测试四:
  • 四、总结:
  • 1. maven设置远程仓库的优先级如下:
  • 2. 设置远程仓库的两种配置方式


零、前言

网上找了很多文章,说maven几种远程仓库的优先级是如下的关系:

settings.xml的profile的仓库 > pom.xml的profile的仓库 > pom.xml的仓库 > 中央仓库

这跟我本地项目编译时看到的不一样,故自己实际测试了一下他们之间的优先级关系,若有不对的地方欢迎指出,共同进步。

也有可能是版本造成的差异,本次测试使用的maven版本为3.6.3

若需要了解settings文件个元素的详细信息,请走传送门:Maven的settings配置文件详解

若需要了解私服的详细操作,请走传送门:Maven私服详解

一、Maven设置远程仓库

前面也说了,一共有四种方式:

  • 中央仓库,可以理解为settings.xml里的mirror,因为它就起一个代理作用
  • settings.xml的profile的仓库
  • pom.xml的profile仓库
  • pom.xml的仓库

后面为了描述简洁,都采用的叫简洁方式进行描述,读者一一对应吧。

二、测试使用到的settings.xml和pom.xml

1. 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>D:\IDEA\Maven\repository</localRepository>

    <!-- 配置访问远程服务器所需的用户信息,此处多为个人或公司私服的账号信息 -->
    <servers>
		<!-- 这里每个server的id都必须与后面(不管是再settings文件中还是pom文件中)的私服仓库id一样,否则会连接不上私服 -->
        
        <!-- pom文件中用到的账号信息 -->
        <server>
            <id>nexus-maven-pom-profile</id>
            <username>admin</username>
            <password>admin</password>
        </server>

        <server>
            <id>nexus-maven-pom-repository</id>
            <username>admin</username>
            <password>admin</password>
        </server>

		<!-- mirror中用到的账号信息 -->
        <server>
            <id>nexus-maven-mirror</id>
            <username>admin</username>
            <password>admin</password>
        </server>

		<!-- settings文件中profile用到的账号信息 -->
        <server>
            <id>maven-releases</id>
            <username>admin</username>
            <password>admin</password>
        </server>

        <server>
            <id>maven-snapshots</id>
            <username>admin</username>
            <password>admin</password>
        </server>
    </servers>

    <mirrors>
        <mirror>
          <id>aliyun-maven-mirror</id>
          <mirrorOf>central</mirrorOf>
          <name>aliyun Maven</name>
          <url>https://maven.aliyun.com/repository/public</url>
        </mirror>
        
        <mirror>
            <id>nexus-maven-mirror</id>
            <mirrorOf>*</mirrorOf>
            <name>private maven</name>
            <url>http://localhost:8081/repository/maven-public/</url>
        </mirror>
    </mirrors>

    <profiles>

        <!-- profile方式配置阿里云Maven -->
        <profile>
            <id>maven-aliyun</id>
            <repositories>
                <repository>
                    <id>aliyun</id>
                    <name>aliyun maven</name>
                    <url>https://maven.aliyun.com/repository/public</url>
                    <releases>
                        <enabled>true</enabled>
                        <updatePolicy>daily</updatePolicy>
                        <checksumPolicy>warn</checksumPolicy>
                    </releases>
                    <snapshots>
                        <enabled>false</enabled>
                        <updatePolicy>always</updatePolicy>
                    </snapshots>
                </repository>
            </repositories>
        </profile>

        <!-- 配置私服Maven -->
        <profile>
            <id>maven-nexus</id>
            <repositories>
                <repository>
                    <id>maven-releases</id>
                    <name>releases</name>
                    <url>http://localhost:8081/repository/maven-releases/</url>
                    <releases><enabled>true</enabled></releases>
                    <snapshots><enabled>true</enabled></snapshots>
                </repository>
                <repository>
                    <id>maven-snapshots</id>
                    <name>snapshots</name>
                    <url>http://localhost:8081/repository/maven-snapshots/</url>
                    <releases><enabled>true</enabled></releases>
                    <snapshots><enabled>true</enabled></snapshots>
                </repository>
            </repositories>
        </profile>
    </profiles>

    <!-- 手动激活profile -->
    <activeProfiles>
		<activeProfile>maven-aliyun</activeProfile>
		<activeProfile>maven-nexus</activeProfile>
    </activeProfiles>
</settings>

2. pom.xml

说明:后面两个依赖都必须从私服中获取,私服中也有fastjson依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>ttest</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>

        <dependency>
            <groupId>org.ob</groupId>
            <artifactId>json</artifactId>
            <version>1.0</version>
        </dependency>

        <dependency>
            <groupId>org.example</groupId>
            <artifactId>tttttt</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>

    <!-- pom文件中设置的远程仓库 -->
    <repositories>
        <repository>
            <id>nexus-maven-pom-repository</id>
            <url>http://localhost:8081/repository/maven-public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

 <!-- pom文件中profile设置的远程仓库 -->
    <profiles>
        <profile>
            <id>profile-test</id>
            <activation>
                <!-- 为方便测试此处设置自动激活 -->
                <activeByDefault>false</activeByDefault>
            </activation>
            <repositories>
                <repository>
                    <id>nexus-maven-pom-profile</id>
                    <url>http://localhost:8081/repository/maven-public/</url>
                    <releases>
                        <enabled>true</enabled>
                    </releases>
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>
            </repositories>
        </profile>
    </profiles>
</project>

三、测试

上面settings文件和pom文件中各自两种方式都设置了远程仓库,即settings文件中的mirror、profile和pom文件的profile、repository四个地方设置远程仓库,测试一即再此情况下进行测试。

测试一:

对于这个初始状态,执行编译(每次编译之前均要清空本地仓库),输入结果如下:

maven 仓库搜索优先级 maven配置文件优先级_xml


可以看到,三个依赖都是从mirrors中配置的私服里(私服中已存在fasjson)下载的

测试二:

将settings文件中配置的第二个mirror注释掉,settings文件做如下修改,然后清空本地仓库继续如上测试

<mirrors>
    <mirror>
      <!-- 唯一标识一个mirror -->
      <id>aliyun-maven-mirror</id>
      <!-- 指定该镜像代替的时那个仓库,例如central就表示代替官方的中央库,*表示所有仓库都是用该镜像,!表示该仓库除外
           <mirrorOf>*, ! central</mirrorOf> 表示所有的远程仓库 central除外,都使用该阿里云镜像
       -->
      <mirrorOf>central</mirrorOf>
      <name>aliyun Maven</name>
      <url>https://maven.aliyun.com/repository/public</url>
    </mirror>

<!--        <mirror>-->
<!--            <id>nexus-maven-mirror</id>-->
<!--            <mirrorOf>*</mirrorOf>-->
<!--            <name>private maven</name>-->
<!--            <url>http://localhost:8081/repository/maven-public/</url>-->
<!--        </mirror>-->
</mirrors>

编译结果:

maven 仓库搜索优先级 maven配置文件优先级_maven 仓库搜索优先级_02


可以看到,三个依赖都是从profiles设置的仓库中下载的,并没有使用pom文件中设置的仓库地址。

测试三:

将profile的状态改为未激活,settings文件做如下修改,然后清空本地仓库继续如上测试

<!-- 手动激活profile -->
    <activeProfiles>
<!--        <activeProfile>maven-aliyun</activeProfile>-->
<!--        <activeProfile>maven-nexus</activeProfile>-->
    </activeProfiles>

测试结果如下所示:

maven 仓库搜索优先级 maven配置文件优先级_maven 仓库搜索优先级_03


可以看到,settings文件中没有设置远程仓库是,使用pom文件里profile设置的仓库而不是repository设置的仓库

测试四:

将pom文件中的profile设置为未激活状态,即把activeByDefault的值设为false,如下所示,然后清空本地仓库继续如上测试

<profiles>
    <profile>
        <id>profile-test</id>
        <activation>
            <!-- 为方便测试此处设置自动激活 -->
            <activeByDefault>false</activeByDefault>
        </activation>
        <repositories>
            <repository>
                <id>nexus-maven-pom-profile</id>
                <url>http://localhost:8081/repository/maven-public/</url>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                    <enabled>true</enabled>
                </snapshots>
            </repository>
        </repositories>
    </profile>
</profiles>

测试结果如下:

maven 仓库搜索优先级 maven配置文件优先级_远程仓库_04


可以看到, 只有前面三种都不这是远程仓库时,才会使用repository设置的仓库。

四、总结:

1. maven设置远程仓库的优先级如下:

中央仓库(settings里的mirror,未配置默认为central)> settings文件的profile设置 > pom文件的profile设置 > pom文件的repository设置

故整体顺序就是按照此优先级方式去找:

当从中央仓库中找不到资源时,去settings文件的profile设置的远程仓库中去找,找不到再去pom文件的profile设置中去找,
还找不到去pom文件的repository设置中去找,若还找不到则会报错。

注意:
这有一个前提,那就是settings文件里配置的mirror中mirrorOf的值不能有*,否则即使在中央仓库的镜像中找不到也不会去其它仓库(profile)中找了。

简单测试下,将settings文件的第二个mirror的url改为中央仓库地址,如下,删除本地仓库,编译测试

<mirrors>
    <mirror>
      <id>aliyun-maven-mirror</id>
      <mirrorOf>central</mirrorOf>
      <name>aliyun Maven</name>
      <url>https://maven.aliyun.com/repository/public</url>
    </mirror>
    
    <-- 该镜像并不能获取到后两个依赖 -->
    <mirror>
        <id>repo</id>
        <mirrorOf>*</mirrorOf>
        <name>private maven</name>
        <url>https://repo.maven.apache.org/maven2/</url>
    </mirror>
</mirrors>

结果如下:repo仓库获取不到jar包,但是并没有去能获取到jar的profile设置的仓库里找。

maven 仓库搜索优先级 maven配置文件优先级_maven_05

2. 设置远程仓库的两种配置方式

若需获取两种方式的详细配置文件请走传送门:Maven的settings配置文件详解 里面的第三部分内容给出了详细的settings文件

方式一:

(此方式适合于个人使用,即只涉及到中央仓库和个人的私服,当不涉及其它仓库时,此方式设置最为简洁,若涉及到其它仓库则只能使用第二种方式)

此种方式配置两个mirror镜像,第一个配置默认的central中央仓库的代理镜像,第二个配置一个私有仓库,将所有中央仓库里没有的jar包都放这里,同时将mirrorOf的值改为*,也就是上面测试一的配置情形。此时不用再其它任何地方设置远程仓库,即使设置了也没用,原因上面已经给出了。

这种方式的缺点显而易见,当需要使用其它仓库时,就会出问题了,因为不可能把其它仓库的所有内容都放到你的私服上去,故而有了第二种方式。

<mirrors>
    <mirror>
      <id>aliyun-maven-mirror</id>
      <mirrorOf>central</mirrorOf>
      <name>aliyun Maven</name>
      <url>https://maven.aliyun.com/repository/public</url>
    </mirror>
    
    <mirror>
        <id>nexus-maven-mirror</id>
        <mirrorOf>*</mirrorOf>
        <name>private maven</name>
        <url>http://localhost:8081/repository/maven-public/</url>
    </mirror>
</mirrors>

方式二:

(推荐使用)

只设置一个中央仓库的代理镜像,其它仓库通过settings文件的profile或pom文件引入,如下所示,也就是上面测试二、三、四的配置情形。

<mirrors>
    <mirror>
      <id>aliyun-maven-mirror</id>
      <mirrorOf>central</mirrorOf>
      <name>aliyun Maven</name>
      <url>https://maven.aliyun.com/repository/public</url>
    </mirror>                      
</mirrors> 

<profiles>
   <profile>
       <id>maven-aliyun</id>
       <repositories>
           <repository>
               <id>aliyun-profile</id>
               <name>aliyun maven</name>
               <url>https://maven.aliyun.com/repository/public</url>
               <releases>
                   <enabled>true</enabled>
                   <updatePolicy>daily</updatePolicy>
                   <checksumPolicy>warn</checksumPolicy>
               </releases>
               <snapshots>
                   <enabled>false</enabled>
                   <updatePolicy>always</updatePolicy>
               </snapshots>
           </repository>
       </repositories>
   </profile>
   
   <!-- 配置私服Maven -->
   <profile>
       <id>maven-nexus</id>
       <repositories>
           <repository>
               <id>maven-releases</id>
               <name>releases</name>
               <url>http://localhost:8081/repository/maven-releases/</url>
               <releases><enabled>true</enabled></releases>
               <snapshots><enabled>true</enabled></snapshots>
           </repository>
           <repository>
               <id>maven-snapshots</id>
               <name>snapshots</name>
               <url>http://localhost:8081/repository/maven-snapshots/</url>
               <releases><enabled>true</enabled></releases>
               <snapshots><enabled>true</enabled></snapshots>
           </repository>
       </repositories>
   </profile>
</profiles>

<!-- 手动激活profile -->
<activeProfiles>
   <!--<activeProfile>jdk-1.8</activeProfile>-->
   <activeProfile>maven-aliyun</activeProfile>
   <activeProfile>maven-nexus</activeProfile>
</activeProfiles>