MAVEN版本: 3.6.1 参考: http://www.voidcn.com/article/p-kufgcswl-mv.html

maven 是什么

balabala…

maven仓库 — repository

本地仓库 VS 远程仓库
运行Maven的时候,Maven所需要的任何构件都是直接从本地仓库获取的。
如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。

本地仓库

  1. Maven缺省的本地仓库地址为${user.home}/.m2/repository 。也就是说,一个用户会对应的拥有一个本地仓库。
  2. 你也可以自定义本地仓库的位置,修改${user.home}/.m2/settings.xml 中如下内容:
<settings>
 	<localRepository>E:\maven\repository</localRepository>
</settings>
  1. 你还可以在运行时指定本地仓库位置: mvn clean install -Dmaven.repo.local=YOUR_LOCAL_REPO

远程仓库

了解了本地仓库,接着了解一下Maven缺省的远程仓库,即Maven中央仓库。

这个Maven中央仓库是在哪里定义的呢?

${M2_HOME}/lib/maven-model-builder-3.6.1.jar ,打开该文件,能找到超级POM:/org/apache/maven/model/pom-4.0.0.xml ,定义来默认对中央仓库:central.

mvn仓库配置多个镜像激活 maven仓库和镜像_mvn仓库配置多个镜像激活

私服

通常,公司内部会搭建一个内部对maven仓库(私服),我们通常通过私服来获取构件,结构如下图:

mvn仓库配置多个镜像激活 maven仓库和镜像_java_02

Nexus 是比较常用的Maven私用服务器。

图片引用自:

在pom中配置远程仓库

<project>
	<!-- repositories 下面可以配置多个repository, 每个repository有一个唯一的ID-->
   <repositories>
        <repository>
            <id>aliyun</id>
            <name>aliyun</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases><enabled>true</enabled></releases>
            
			<!--snapshots默认是关闭的,需要开启  -->
            <!--禁止从公共仓库下载snapshot构件是推荐的做法,因为这些构件不稳定,且不受你控制,你应该避免使用。
             	但是如果是私服仓库,可以激活snapshot的支持 -->
            <snapshots><enabled>true</enabled></snapshots>
        </repository>
		 <repository>
            <id>huawei</id>
            <name>华为云</name>
            <url>https://repo.huaweicloud.com/repository/maven/</url>
            <releases><enabled>true</enabled></releases>
        </repository>
    </repositories>
    
	<!-- pluginRepositories,这是配置Maven从什么地方下载插件, 同repositories -->
	<pluginRepositories>
        <pluginRepository>
        	<!-- id可以与 repositories中重复 -->
         	<id>aliyun</id>
        </pluginRepository>
    </pluginRepositories>
</project>

setting.xml中配置远程仓库
我们知道了如何在POM中配置远程仓库,还可以在setting.xml中配置仓库。
但是<settings>标签内并不支持<repositories>及<pluginRepositories>, 我们需要利用<profile>来配合使用,最终通过<activeProfiles> 来激活指定的<profile>.

<settings>
     <profiles>     
        <profile>
              <id>dev</id>
              <repositories>
                  <repository>
                  </repository>
              </repositories>
        </profile>      

        <profile>
              <id>test</id>
              <repositories>
                  <repository>
                  </repository>
              </repositories>
        </profile>

         <profile>
              <id>prod</id>
              <repositories>
                  <repository>
                  </repository>
              </repositories>
        </profile>
    </profiles>

     <activeProfiles>
         <activeProfile>dev</activeProfile> 
         <activeProfile>test</activeProfile>  
    </activeProfiles>
</settings>

仓库的优先级

首先申明一个前提:本地仓库优先级最高,接下来我们在以实际上不存的构件为前提下进行测试。

前文了解到,可以在多个地方,每个地方又可以配置多个仓库,那么仓库加载的优先级是如何的呢?
下面我们来综合分析下,假设我们引用一个不存在的构件:

<dependencies>
      <dependency>
           <groupId>org.junit</groupId>
           <artifactId>junit</artifactId>
           <!-- 指定一个不存在的构件-->
           <version>x.y.z</version>
       </dependency>
   </dependencies>

仅在pom中配置多个repository

<repositories>
        <repository>
            <id>huawei</id>
            <name>华为云</name>
            <url>https://repo.huaweicloud.com/repository/maven/</url>
            <releases><enabled>true</enabled></releases>
        </repository>

        <repository>
            <id>aliyun</id>
            <name>阿里云</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases><enabled>true</enabled></releases>
            <!--snapshots默认是关闭的,需要开启  -->
            <!--禁止从公共仓库下载snapshot构件是推荐的做法,因为这些构件不稳定,且不受你控制,你应该避免使用。
             	但是如果是私服仓库,可以激活snapshot的支持 -->
            <snapshots><enabled>false</enabled></snapshots>
        </repository>
    </repositories>

执行命令:mvn clean install -U 来强制更新,结果如下:

mvn仓库配置多个镜像激活 maven仓库和镜像_远程仓库_03


通过执行结果,可以推测出:在<repositories>中定义的顺序先后进行加载,最后再尝试加载中央仓库。

同事在setting.xml中配置多个仓库
在前文的基础上,在setting.xml中配置多个profile,且同时激活多个profile,配置如下:

<settings>
     <profiles>     
        <profile>
              <id>dev</id>
              <repositories>
              	<!--省略 repository url相关配置,下同 -->
                <repository><id>dev2</id> </repository>
                <repository><id>dev1</id></repository>
              </repositories>
        </profile>      

        <profile>
              <id>test</id>
              <repositories>
                  <repository> <id>test1</id> </repository>
                  <repository> <id>test2</id> </repository>
            </repositories>
        </profile>

         <profile>
              <id>prod</id>
               <repositories> 
                  <repository> <id>prod1</id> </repository>
                  <repository> <id>prod2</id> </repository>
           </repositories>
        </profile>
    </profiles>


     <activeProfiles>
         <activeProfile>test</activeProfile> 
         <activeProfile>dev</activeProfile> 
    </activeProfiles>
</settings>

执行命令:mvn clean install -U 来强制更新,结果如下:

mvn仓库配置多个镜像激活 maven仓库和镜像_mvn仓库配置多个镜像激活_04


可以得出结论

  • 首先,加载settings.xml<activeProfiles>激活<activeProfile>,且<activeProfile>会按照定义的先后顺序加载
  • <activeProfile> 内部的<repositories>中的多个仓库,同样按照定义的先后顺序加载
  • 然后, 加载pom.xml中的仓库(按顺序加载)
  • 最后, 会从中央仓库尝试加载。

maven镜像-mirror

通常,有很多依赖(构件)在中央仓库(境外),由于众所周知的原因会下载的很慢,或者压根下载不到,我们可以通过代理(镜像)来实现.
通过镜像的配置mirrorOf,覆盖指定仓库的url,从而实现代理的功能。

mirror并不会影响仓库的加载顺序,而是在确定了仓库之后,改变仓库的请求地址!

配置多个mirror以及镜像的优先级

注意,镜像只能在settings.xml中配置

在前文的基础上,增加mirror配置, 同时为central中央仓库添加 三个镜像:

<settings>
       <mirrors>
        <mirror>
        	
            <id>mirror2</id>
            <!-- 通过mirrorOf 用自身的url 覆盖指定仓库的url-->
            <mirrorOf>central</mirrorOf>
            <!--  <url>https://repo1.maven.org/maven2</url>   -->
            <!-- 这样就不允许直接从中央仓库下载jar包, 必须通过配置的url中下载jar-->
           <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        </mirror>

          <mirror>
            <id>mirror1</id>
            <mirrorOf>central</mirrorOf>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        </mirror>

          <mirror>
            <id>mirror3</id>
            <mirrorOf>central</mirrorOf>
           <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
        </mirror>
    </mirrors>
</settings>

执行mvn clean install -U,强制更新:

mvn仓库配置多个镜像激活 maven仓库和镜像_远程仓库_05


从结果可以得出结论:如果一个仓库匹配到多个mirror,会按照先后顺序进行匹配仅第一个匹配到的mirror有效.

mirrorOf -配符
通过镜像的配置mirrorOf,覆盖指定仓库的url,mirrorOf 中除了指定具体的repository配置对id,maven还支持更高级的用法:

  • * : 所有远程仓库都从该镜像获取
  • *,!repo1 : 除 repo1 远程仓库以外的所有仓库都从该镜像获取
  • repo1,repo2: repo1repo2仓库都从该镜像获取
  • external:* :不在本地仓库的文件才从该镜像获取

mirroor.id – 401 – 20240713 补充
假设有如下配置,遇到401问诶

<mirrors>
     <mirror>
           <id>secureArtifactory</id>
           <mirrorOf>repo1,repo2.....,central,maven-central</mirrorOf>
           <url>https://aaa.bbb.com/artifactory/ccc-group</url>
     </mirror>
  </mirrors>

遇到401 错误
from/to secureArtifactory (https://aaa.bbb.com/artifactory/ccc-group): authentication failed for https://aaa.bbb.com/artifactory/ccc-group/com/xxx/yyy/zzz/4.0.286/zzz-4.0.286.pom, status: 401 Unauthorized -> [Help 1] 则说明访问mirror.id=secureArtifactory 需要配置token认证信息, 同repository类似,需要配置一个同名的server信息即可。

deploy到远程仓库。

  • mvn install 会将项目生成的构件安装到本地Maven仓库,
  • mvn deploy 用来将项目生成的构件分发到远程Maven仓库

本地Maven仓库的构件只能供当前用户使用,在分发到远程Maven仓库(通常是私服)之后,你的同事才能使用到你发布的构建。
pom中配置-distributionManagement

<!-- 部署配置-->
    <distributionManagement>
        <snapshotRepository>
            <id>nexus-snapshot</id>
            <url>http://your_company_nexus_host:port/repository/maven-snapshots/</url>
        </snapshotRepository>
        <repository>
            <id>nexus-release</id>
            <url>http://your_company_nexus_host:port/repository/maven-releases</url>
        </repository>
    </distributionManagement>

Maven区别对待release版本的构件和snapshot版本的构件,
- snapshot为开发过程中的版本,实时,但不稳定,会部署到<snapshotRepository>仓库。
- release版本则比较稳定,会部署到<repository>仓库。

Maven会根据你项目的版本号来判断将构件分发到哪个仓库。

  • 当版本号符合*-SNAPSHOT形式时,会部署到<snapshotRepository> ,注意**-SNAPSHOT(大小写不敏感,但是 - 必须要有)**
  • 其他版本号,会部署到 <repository>

setting.xml配置servers
一般来说,分发构件到远程仓库需要认证,如果你没有配置任何认证信息,你往往会得到401错误。

<!-- 服务发布到目标私服的用户名密码,
     id对应pom.xml中的distributionManagement.repository.id 或者 distributionManagement.snapshotRepository.id一致-->
    <servers>
        <server>
            <id>nexus-snapshot</id>
            <username>deployment</username>
            <password>deployment123</password>
        </server>
        <server>
            <id>nexus-release</id>
            <username>publish</username>
            <password>publish123</password>
        </server>
    </servers>

最后使用mvn deploy部署即可。