1. 引入

  • maven坐标和依赖是一个构件在maven世界中的逻辑表示方式,而构件的物理表示方式是文件。
  • maven通过仓库来统一管理这些构件。
  • maven项目将不再各自存储其依赖文件,只需要声明依赖坐标。
  • maven采用引用的方式将依赖的jar引入进来,不对真实的jar进行拷贝,但是打包的时候,运行需要用到的jar都会被拷贝到安装包

2. 仓库分类

  • 本地仓库
  • 远程仓库: 中央仓库、私服、其他公共仓库

2.1 本地仓库

  • 在安装maven后本地仓库并不存在,当我们执行第一条maven命令的时候才会创建本地仓库。
  • 默认情况下,maven本地仓库默认地址是~/.m2/respository目录,
  • 用户可以自定义本地仓库目录,在~/.m2/settings.xml文件中进行修改:

    <localRepository>/Users/john/dev/repository</localRepository>
  • 下载构件:从远程仓库下载到本地仓库目录中
  • 使用本地项目构件:将本地项目构件安装到maven本地仓库

    john:demo1 john$ mvn clean install

2.2 远程仓库

  • 本地仓库不存在构件时,需要从远程仓库下载构件。

2.3 中央仓库

  • 在maven的超级pom中可以看到默认的中央仓库。

    • 超级pom:所有maven项目都会继承,其中的配置会自动继承。
    • 超级pom所在文件:${M2_HOME}/lib/maven-model-builder-3.6.3.jar
    • 解压jar文件
    • 查看lib/org/apache/maven/model/pom-4.0.0.xml
    • 找到中央仓库的默认配置:

        <repositories>
          <repository>
            <id>central</id>
            <name>Central Repository</name>
            <url>https://repo.maven.apache.org/maven2</url>
            <layout>default</layout>
            <snapshots>
              <!-- 不从该中央仓库下载快照版本的构件 -->
              <enabled>false</enabled>
            </snapshots>
          </repository>
        </repositories>
  • 默认的中央仓库:

2.4 私服

  • 私服是一种特殊的远程仓库,是架设在局域网内的仓库服务。
  • 私服代理广域网上的远程仓库,供局域网内的maven用户使用。
  • 私服的好处:

    • 节省自己的外网带宽。
    • 加速maven构建。
    • 部署第三方构件。
    • 提高稳定性,增强控制。
    • 降低中央仓库的负荷。

2.5 其他远程仓库

3. 远程仓库配置

3.1 在项目POM中配置远程仓库(项目)

  1. 说明:该配置只对当前项目有效。
  2. 配置信息

    <project>
    ...
        <repositories>
            <repository>
                <id>aliyun-repo</id>
                <name>aliyun repo</name>
                <url>https://maven.aliyun.com/repository/public</url>
                <releases>
                    <enabled>true</enabled>
                    <!-- updatePolicy 默认值daily -->
                    <updatePolicy>daily</updatePolicy>
                    <checksumPolicy>ignore</checksumPolicy>
                </releases>
                <snapshots>
                    <!-- 不下载快照版本构件 --> 
                    <enabled>false</enabled>
                </snapshots>
                <layout>default</layout>
            </repository>
        </repositories>
    ...
    </project>
  3. repositories->repository元素说明

    • repositories元素下可以使用repository子元素声明一个或多个远程仓库。
    • id:远程仓库标识,id名称唯一。注意:maven自带的中央仓库id为central,如果其他的仓库声明也使用该id,会覆盖中央仓库的配置。
    • url:远程仓库地址。
    • releases:用来控制对于发布版本构件的下载。

      • enabled属性表示是否开启发布版本的下载支持。
      • updatePolicy:用来配置maven从远程仓库更新的频率。

        • 默认为daily,表示每天检查一次。
        • never,从不检查更新。
        • always,每次构建都检查更新。
        • interval: X,每隔X分钟检查更新一次(X为任意整数)
      • checksumPolicy:用来配置maven检查校验和文件的策略。

        • 默认为warn,执行构建时给出警告信息。
        • fail,遇到校验和错误,就让构建失败。
        • ignore,让maven完全忽略校验和错误。
    • snapshots:用来控制对于快照版本构件的下载。

      • enabled属性表示是否开启快照版本的下载支持。
      • 快照版本的构件以-SNAPSHOT结尾,发布版本没有这个标识。
    • layoutdefault表示仓库的布局是maven2或者maven3的默认布局,而不是maven1的布局。
  4. 测试远程仓库能否正常拉取依赖

    • 以项目demo1为例。
    • 首先,删除${localRepository}/org/springframework/spring-web目录文件,此时本地仓库无依赖。
    • 切换到项目目录/Users/john/Desktop/demo1,在终端执行mvn compile
    • 查看终端输出。

      john:demo1 john$ mvn compile
      [INFO] Scanning for projects...
      [INFO] 
      [INFO] ---------------------------< com.john:demo1 >---------------------------
      [INFO] Building demo1 1.0-SNAPSHOT
      [INFO] --------------------------------[ jar ]---------------------------------
      Downloading from aliyun-repo: https://maven.aliyun.com/repository/public/org/springframework/spring-web/5.2.1.RELEASE/spring-web-5.2.1.RELEASE.pom
      Downloaded from aliyun-repo: https://maven.aliyun.com/repository/public/org/springframework/spring-web/5.2.1.RELEASE/spring-web-5.2.1.RELEASE.pom (1.9 kB at 5.0 kB/s)
      Downloading from aliyun-repo: https://maven.aliyun.com/repository/public/org/springframework/spring-web/5.2.1.RELEASE/spring-web-5.2.1.RELEASE.jar
      Downloaded from aliyun-repo: https://maven.aliyun.com/repository/public/org/springframework/spring-web/5.2.1.RELEASE/spring-web-5.2.1.RELEASE.jar (1.4 MB at 6.3 MB/s)
      [INFO] 
      [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ demo1 ---
      [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
      [INFO] skip non existing resourceDirectory /Users/john/Desktop/demo1/demo1/src/main/resources
      [INFO] 
      [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ demo1 ---
      [INFO] Nothing to compile - all classes are up to date
      [INFO] ------------------------------------------------------------------------
      [INFO] BUILD SUCCESS
      [INFO] ------------------------------------------------------------------------
      [INFO] Total time: 1.565 s
      [INFO] Finished at: 2019-12-15T13:38:51+08:00
      [INFO] ------------------------------------------------------------------------
    • 观察Downloading from aliyun-repo后面就是在pom文件中配置的远程仓库,aliyun-repo是定义的仓库id。 在本地仓库缺少依赖后,就会从配置的远程仓库下载依赖。

3.2 在用户配置中配置镜像仓库(全局)

  1. 说明:该配置对所有使用该配置的项目都有效。
  2. 什么是镜像仓库?

    • 如果仓库X可以提供仓库Y所有的内容,那么就可以认为X是Y的一个镜像。
    • 任何一个可以从Y获取的构件,都可以从它的镜像中获取。
    • 可以采用镜像的方式配置远程仓库,镜像在settings.xml中进行配置,对所有使用该配置的maven项目起效。
  3. 配置镜像仓库

    <mirrors>
        <mirror>
          <id>aliyun-maven</id>
          <name>aliyun maven</name>
          <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
          <mirrorOf>central</mirrorOf>        
        </mirror>
    </mirrors>
  4. 配置解释

    • mirrors元素下包含多个mirror子元素,每个mirror元素表示一个远程镜像。
    • id:镜像id,唯一标识。
    • name:镜像名称。
    • url:镜像地址
    • mirrorOf:指定哪些远程仓库的id使用这个镜像去下载构件,这个对应pom.xml文件中repository元素的id。就是表示这个镜像是给哪些pom.xml文件中的远程仓库使用的,这里面需要列出远程仓库的id,多个之间用逗号隔开。
    • mirrorOf配置语法:

      • <mirrorOf> * </mirrorOf>:匹配所有远程仓库。
      • <mirrorOf>external: * </mirrorOf>:匹配所有不在本机上的远程仓库。
      • <mirrorOf> repo1, repo2 </mirrorOf>:匹配仓库repo1和repo2,多个仓库之间使用逗号分割。
      • <mirrorOf> *, !repo1 </mirrorOf>:匹配所有远程仓库,除了仓库repo1,使用感叹号(!)将仓库从匹配中排除。
  5. 注意
    镜像仓库完全屏蔽了被镜像仓库,当镜像仓库不稳定或者停止服务的时候,maven无法自动切换到被镜像仓库,因此将会无法下载构件。
  6. 结合私服使用
    由于私服可以代理所有远程仓库(包含中央仓库),因此对于组织内部的maven用户来说,使用一个私服地址就等于使用了所有需要的外部仓库。

4. 仓库布局

  1. 仓库布局方式
    任何一个构件都有其唯一的坐标,根据坐标可以定义其在仓库中的唯一路径。
  2. 举例

    • 以spring-web的依赖为例
    • 项目demo1 pom文件的依赖

      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-web</artifactId>
          <version>5.2.1.RELEASE</version>
      </dependency>
    • 查看spring-web的jar包在本地仓库中的位置。

      • /Users/john/dev/repository/org/springframework/spring-web/5.2.1.RELEASE/spring-web-5.2.1.RELEASE.jar
      • /Users/john/dev/repository是本地仓库目录。
      • 构件的目录路径为groupId/artifactId/version/
      • 构件名称为:artifactId-version[-classifier].packaging, packaging默认为jar。
  3. maven如何定位构件路径

    1. 将groupId中的句点分隔符(.)转换成路径分隔符(/),同时在后面追加一个路径分隔符(/)。

      • org.springframework--->org/springframework/
    2. 将artifactId拼接在1的路径上, 同时在后面追加一个路径分隔符(/)。

      • org/springframework/spring-web/
    3. 将version拼接在2的路径上,同时在后面追加一个路径分隔符(/)。

      • org/springframework/spring-web/5.2.1.RELEASE/
    4. 将构件名称拼接在3的路径上。

      • org/springframework/spring-web/5.2.1.RELEASE/spring-web-5.2.1.RELEASE.jar

5. 仓库如何解析依赖

  1. 当本地仓库没有依赖构件的时候,maven会自动从远程仓库下载;
  2. 当依赖版本为快照版本的时候,maven会自动找到最新的快照。
  3. 依赖解析机制:

    • 依赖范围是system的时候,maven直接从本地文件系统解析构件。
    • 根据依赖坐标计算仓库路径后,尝试直接从本地仓库寻找构件,如发现相应构件,则解析成功。
    • 如果本地仓库构件不存在,并且依赖的版本是显示的发布版本构件,则遍历所有的远程仓库,发现后 下载并解析使用。

6. 仓库检索

  1. Sonatype(中央仓库):https://search.maven.org/
  2. Sonatype Nexus: https://repository.sonatype.org/
  3. MVNRepository:https://mvnrepository.com/

John
10 声望2 粉丝

好记性不如烂笔头。


引用和评论

0 条评论