转载

Maven学习3: 仓库

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>
  • 默认的中央仓库:

    • https://repo.maven.apache.org/maven2/

2.4 私服

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

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

2.5 其他远程仓库

  • aliyun: http://maven.aliyun.com/nexus...

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
        
      • checksumPolicy :用来配置maven检查校验和文件的策略。

        warn
        fail
        ignore
        
    • 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
      
  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/
原文  https://segmentfault.com/a/1190000021291114
正文到此结束
Loading...