Maven仓库

maven

1、仓库的种类

  1. 本地仓库

    本地仓库默认位置在 %MAVEN_HOME%/.m2/repository目录下,也可以在setting.xml文件中指定仓库位置。

    在下载依赖的时候会先从本地仓库查找,如果没有才会到私服或者中央仓库下载到本地仓库。在maven的生命周期install的时候也会将构建保存到本地仓库。

  2. 远程仓库

    • 中央仓库

      由于原始的本地仓库是什么都没有的,所以maven的默认安装配置文件(%MAVEN_HOME%/lib/maven-model-builder-x.jar中/org/apache/maven/model/pom-4.0.0.xml)配置了默认的中央仓库地址。

      中央仓库上面包含了非常全面的开源java构建,但下载比较慢。

    • 私服

      私服是一种特殊的远程仓库,和内网搭建的gitlab差不多,用于保存公司内部的东西。还能提高下载速度。

    • 其他公共库

2、配置远程仓库

order-of-maven-repositories-in-settings-xml

how-to-set-order-of-repositories-in-maven-settings-xml

Maven仓库理解和优先级

​ 为了提高依赖下载速度和共享公司内部的私有依赖,我们需要远程仓库来满足这个需求。远程仓库可以配置在共享的settings.xml配置文件中供各个项目公用,也可以配置在pom.xml文件中供单个项目使用。这个时候就会有一个先后顺序的问题(坑死我了),根据我查了两天的资料这里总结一下。

**本地仓库 > settings.xml下的profiles.profile.repositories.repository > pom.xml下的profiles.profile.repositories.repository > pom.xml下的repositories.repository **

也就是说本地仓库优先级最高,其次是settings.xml下的,最后才是pom.xml下的。这里面由于settings.xmlpom.xml文件的repositories标签下可以配置多个仓库,那么他们之间的顺序又是什么呢?按照直觉来说就是配置文件的配置顺序,但是在Maven3之前却是有问题的:MNG-4400。好在之后已经修复好了,是按照配置文件的顺序来访问的。

setting.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">
  <!-- 
      settings.xml中的profile元素是pom.xml中profile元素的裁剪版本
      它包含了
        1. activation,
        2. repositories
        3. pluginRepositories 
        4. properties
      这里的profile元素只包含这四个子元素是因为这里只关心构建系统这个整体(这正是settings.xml文件的角色定位),而非单独的项目对象模型设置。  
      如果一个settings中的profile被激活,它的值会覆盖任何其它定义在POM中或者profile.xml中的带有相同id的profile。 
    -->
  <profiles>
    <!-- 私服配置 -->
    <profile>
      <id>nexus</id>
      <repositories>
        <!-- 先访问这个查找依赖-->
        <repository>
          <id>nexus-1</id>
          <url>http://10.5.xx.xx/nexus/repository/maven-public/</url>
          <releases>
            <enabled>true</enabled>
          </releases>
        </repository>
        <!-- 再访问这个查找依赖-->
        <repository>
          <id>nexus-2</id>
          <url>http://172.19.xx.xx:xxxx/nexus/content/repositories/thirdparty</url>
          <releases>
            <enabled>true</enabled>
          </releases>
        </repository>
      </repositories>
    </profile>
  </profiles>
  <activeProfiles>
    <activeProfile>nexus</activeProfile>
  </activeProfiles>
</settings>


pom.xml

注意release版本的检查更新策略一般没什么用


<!-- pom.xml配置-->
<project>
  <repositories>
    <repository>
      <!--
        任何一个仓库的id必须是唯一的,且Maven自带的仓库使用的id为central,如果其他的仓库声明使用了
        该id,那么会覆盖中央仓库的配置。
      -->
      <id>jboos</id>
      <!--该仓库的名字,便于阅读 -->
      <name>JBoss Repository</name>
      <!-- 该远程仓库的地址-->
      <url>http://xxxx/xxxx</url>
      <!-- 该远程仓库的发行版下载配置 -->
      <releases>
          <!-- 如果为true,表示开启该远程仓库发行版的下载支持 -->
         <enabled> true </enabled>
          <!--远程仓库检查更新频率,默认为daily,其他的有never\always -->
          <updatePolice>daily</updatePolice>
          <!--检查校验和文件失败时策略,相当于md5校验?warn\fail\ignore-->
          <checksumPolicy>ignore</checksumPolicy>
      </releases>
      <!--该远程仓库快照片下载配置-->
      <snapshots>
         <enabled>
           false
         </enabled>
      </snapshots>
      <layout>default</layout>
    </repository>
  </repositories>
</project>

4、镜像

maven的mirror和repository加载顺序

​ 如果仓库A拥有仓库B的所有内容,那么A就是B的一个镜像。由于maven中央仓库在国外,所以下载起来比较慢,此时可以用国内的阿里云镜像来代替,可以在setting.xml文件中配置。

<settings>
  <mirrors>
    <mirror>
      <!--镜像ID-->
      <id>alimaven</id>
      <!--镜像名查-->
      <name>aliyun maven</name>
      <!--镜像地址,这是阿里的-->
      <url>https://maven.aliyun.com/repository/public</url>
      <!--镜像那个仓库? 可以指定多个,也可以用*等.这里的central就是中央仓库-->
      <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>
</settings>
4.1 镜像和仓库的区别

​ 镜像是用来加速依赖下载的,仓库是存放构建的地方。比如说内网仓库,我们公司内部开发的一些项目jar包肯定不能放公共仓库,都是放在内网仓库,供各个项目复用。所以这个jar包在公共仓库中是找不到的,需要配置一下远程仓库地址,也就是在POM中配置repository;而镜像则是再setting中配置的对某个仓库的代理访问,加速下载。

4.2 镜像使用误区

mirrorOf是非常容易引起混淆的,我在网上看到很多对这个的配置理解有误导致配了一些没用的镜像。

  • 误区1: 多个mirrorOf配置相同

    多个镜像配置都镜像同一个仓库,可能想法是第一个例如阿里云的镜像没有的话走第二个腾讯云的镜像,腾云的镜像没有走华为云等等。其实只有第一个阿里云的镜像会生效,如果阿里云找不到就不会使用第二个腾讯的了。

    <mirrors>
        <mirror>
            <name>aliyun</name>
            <url>xxxx</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
        <mirror>
            <name>tencent</name>
            <url>xxxx</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
        <mirror>
            <name>huawei</name>
            <url>xxxx</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>
    
  • 误区2: 不理解 * 的用法

    以为配置 * 就是镜像所有的仓库,其实 * 这种语法优先级是最低的。maven查找镜像的顺序是先根据mirrorOf精准匹配(如"a".equlse(b))一轮,如果没有找到,再使用类似正则匹配那样再模糊匹配一轮。所以下面这个配置rep1的优先级是高于*的。

    <mirrors>
        <mirror>
            <name>aliyun</name>
            <url>xxxx</url>
            <mirrorOf>*</mirrorOf>
        </mirror>
        <mirror>
            <name>tencent</name>
            <url>xxxx</url>
            <mirrorOf>rep1</mirrorOf>
        </mirror>
    </mirrors>
    

5、发布自己的构件

​ 例如公司内部的技术团队分为基础设施研发团队和业务开发团队,基础设施研发团队开发好一个功能之后发布到内网仓库中供各个部门使用,这时候就需要配置一下,告诉maven我这个构件发布到哪里,下面distributionManagement标签就是干这个事情的。

</project>
  <distributionManagement>
    <repository>
      <!-- 远程仓库id -->
      <id>nexus-releases</id>
      <!--名称,方便阅读-->
      <name>Nexus Release Repository</name>
      <!--地址-->
      <url>http://192.168.0.152:8088/content/repositories/releases/</url>
    </repository>
    <snapshotRepository>
      <id>nexus-releases</id>
      <name>Nexus Snapshot Repository</name>
      <url>http://192.168.0.152:8088/content/repositories/snapshots/</url>
    </snapshotRepository>
  </distributionManagement>
</project>

6、快照版本

每一个项目都有自己的版本,例如1.2.3.RELEASE表示这是一个稳定的发行版,1.2.4.SNAPSHOT表示这是一个不稳定版本,代码可能随时变更。当一个项目或者构件被标记为SNAPSHOT的时候,MAVEN在每次构建时都会去仓库中检查该依赖是否有了更新,有则下载替换;使用场景是这样的,在一个协作开发的项目中,模块A依赖了模块B,而模块B正在进行新功能的开发,代码随时会变更,而模块A此时正在和模块B进行联调。模块A需要及时获取最新的模块B,此时如果还是使用1.2.3这样的版本方式的话模块A是拿不到最新代码的。那么当模块B将版本号命名为 1.2.4-SNAPSHOT 这样声明为快照版的时候,maven在每次构件之前都会去检查远程仓库中是否有最新版本。

Q.E.D.