Maven坐标和依赖是任何一个构件在Maven世界中的逻辑表示方式;而构件的物理表示方式是文件,Maven通过仓库来统一管理这些文件。

    Maven仓库

      在Maven的世界中,任何一个依赖、插件或者项目构建的输出,都可以称为一个构件。如项目依赖log4j-1.2.15.jar是一个构件,插件maven-compiler-plugin-2.0.3.jar是一个构件,我们自己的Maven项目构建完成后的输出.jar/war文件也是一个构件。任何一个构件都有一组坐标唯一标识。在我们项目开发中,往往可能会涉及到十几个甚至几十个Maven项目,可能大部分项目都需要log4j来打印日志,那么是否我们需要在每一个Maven项目中buildpath一份log4j的java类库呢?答案显然不是,本着重用性的原则,我们最好把这个java类库放在一个地方,所有要用到log4j的Maven项目都共用一份log4j java类库,那么这个地方就是Maven仓库。为了实现重用,项目构架完毕后生成的构件也可以安装或者部署到Maven仓库中供其他Maven项目使用。

  仓库布局

      任何一个构件都有其唯一坐标,根据这个坐标可以定义其在仓库中的唯一存储路径,这便是Maven的仓库布局方式。例如log4j:log4j:1.2.15这一依赖,那么其对应的仓库路径为log4j/log4j/1.2.15/log4j-1.2.15.jar,改路径与pom对应的坐标关系为groupId/artifactId/version/artifactId-version.packaging。

  仓库的分类

       对于Maven来说,仓库只分为两类:本地仓库和远程仓库。当Maven根据坐标寻找构件的时候,它会首先查看本地仓库,如果本地仓库存在构件,则直接使用;如果本地仓库不存在此构件,或者需要查看是否有更新的构件版本,Maven就会去远程仓库查找,发现需要的构件之后,下载到本地仓库再使用。如果本地仓库和远程仓库都没有需要的构件,Maven就会报错。

       中央仓库是Maven核心自带的远程仓库,它包含了绝大部分开源的构件。在默认配置下,当本地没有找到Maven需要的构件的时候,它就会自动尝试从中央仓库下载。

       私服是另一种特殊的远程仓库,稍有规模的企业都会在局域网内搭建这样一个私服,用其代理所有外部的远程仓库,不仅速度更快,而且内部项目还能部署到私服上供其他项目使用。

       其他公开的远程仓库,常见有Java.net.Maven库和JBoss Mavn库。

  

maven构建架构设计_远程仓库

       本地仓库

       一般来说,在Maven项目目录下没有诸如lib/这样用来存放依赖文件的目录。当Maven执行编译或测试时,如果需要使用依赖文件,它总是基于坐标使用本地仓库的依赖文件。

       默认情况下,每个Maven用户在自己的用户目录下都有一个路径名为.m2/repository/的仓库目录,一般在C盘的用户目录下。实际上.m/目录下还有一个setting.xml文件(一般使用IDE Maven插件的朋友会发现,setting.xml文件已经自动复制过来了,如果没有,我们可以手动从Maven的安装目录下的conf文件夹下复制setting.xml到.m/目录下)。Repository目录里放置的就是本地需要的所有构件。由于系统盘磁盘大小有限,而一个.m2文件随便可以达到几个G甚至十几个G,所以我们有强烈的愿望,希望能把本地仓库搬家,这个倒也不难,只需要在setting.xml文件修改一下如下配置即可:

<localRepository>e:/MavenRepository</localRepository>

       这个即为本地仓库的地址。

       Maven安装好后,如果不执行任何Maven命令,本地仓库目录是不存在的。当用户输入第一条Maven命令之后,Maven才会创建本地仓库,然后根据配置和需要,从远程仓库下载构件至本地仓库。

  中央仓库

   由于最原始的本地仓库是空的,Maven必须知道至少一个可用的远程仓库,才能在执行Maven命令的时候下载到需要的构件。中央仓库就是这样一个默认的远程仓库,Maven安装文件自带了中央仓库的配置。我们可以打开Maven的安装目录,在lib/下找到maven-model-builder.jar(每个人版本可能不一样),然后利用反编译工具,可以找到org/apache/maven/model/pom-4.0.0.xml文件,可以看到如下配置:

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

  私服

      私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,当Maven需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部远程仓库下载,缓存在私服上之后,再为Maven的下载提供服务。

  

maven构建架构设计_远程仓库_02

      私服强大之处在于:

         1、能节省自己的外网宽带。

         2、加速Maven构建。不停地连接外部仓库是十分耗时的,但是Maven的一些内部机制(如快照更新检查)要求Maven在执行构建的时候不停地检查远程仓库数据。因此,当项目配置了很多外部远程仓库的时候,构建的速度会被大大降低。使用私服可以很好地解决这个问题。

         3、部署第三方构建。

         当某个构件无法从任何一个外部远程仓库获得,怎么办?很典型的例子是,JDBC驱动由于版权因素不能发布到公共仓库中。建立私服后,便可以将这些构件部署到这个内部仓库中,供内部的Maven项目使用。

         4、安全性。从两点上得到保障,一是及时暂时没有Internet连接,由于私服中已经缓存了大量构件,Maven仍能正常运行;二是有些私服还提供权限管理、仓库分区等服务;

         5、降低中央仓库的负荷,如果没有私服,每个人使用Maven都从中央仓库下载,中央仓库承受的压力,下载的速度可想而知。

  远程仓库的配置

  很多情况下,默认中央仓库无法满足项目的需求,可能项目需要的构件存在另外一个远程仓库中,如JBOSS Maven仓库。这时,我们可以在POM如下配置仓库:

<project>
         ...
         <repositories>
                  <repository>
                          <id>jboss</id>
                          <name>JBoss Repository</name>
      <url>http://repository.jboss.com/maven2/</url>
                          <releases>
                                   <enabled>true</enabled>
                          </releases>
                          <snapshots>
                                   <enabled>false</enabled>
                          </snapshots>
                          <layout>default</layout>
                  <repository>
         </repositories>
</project>

  在repositories元素下,可以使用repository子元素 一个或者多个远程仓库。任何一个仓库声明的id必须是唯一的,该配置中的url指向了仓库的地址,一般采用http协议,releases元素的enabled的值为true,snapshots元素的enabled的值为false,则说明,只会下载远程仓库发布版本的构件而不会下载快照版本的构件。对于releases和snapshots,它们还包含了另外两个元素updatePolicy和checkSumPolicy。

<releases>
         <updatePolicy>daily</ updatePolicy>
          <enabled>true</enabled>
          <checkSumPolicy>ignore</checkSumPolicy>
</releases>

   updatePolicy为从Jboss仓库检查的频率,值可以为daily(每天)、never(从不)、always(每次构建都检查)、Interval(每隔多少分钟检查一次)。

   checkSumPolicy用来配置Maven检查检验和文件的策略,当构件被部署到Maven仓库时,会同时部署对应的检验和文件。在下载构件的时候,Maven会验证检验和文件。如果验证检验失败,当checkSumPolicy为warn时,Maven会在执行构件时输出警告信息,其他可用的值有:fail当验证检验失败,就让Maven构建失败;ignore完全忽略校验和失误。

   远程仓库的验证

  大部分仓库都无需认证就可以访问,但有时处于安全方面的考虑,我们需要提供认证信息才能访问远程仓库。为了防止非法的仓库访问,管理员往往会提供一组用户名和密码,这时,为了能访问仓库,就需要在setting.xml文件中配置:

<settings>
    ...
         <servers>
                  <server>
                          <id>
                           my-proj
                          </id>
                          <username>
                           repo-user
                          </username>
                          <password>
                           repo-password
                          </password>
                  </server>
         </servers>
</settings>

  etting文件中的server的id必须与pom文件的需要认证的repository元素的id一致,正是此id将认证信息和仓库配置联系在了一起。

     将构件部署至远程仓库

  编辑项目pom.xml文件

<project>
         ...
         <distributionManagement>
                  <repository>
                          <id>proj-releases</id>
                     <name>proj releases repository</name>
                   <url>http://192.168.2.11:1521/proj-releases/</url>
                  </repository>
                  <snapshotRepository>
                           <id>proj-snapshots</id>
                    <name>proj snapshots repository</name>
                <url>http://192.168.2.11:1521/projsnapshots/</url>
                  </snapshotRepository>
         </distributionManagement>
</project>

  往远程仓库部署构件的时候,往往需要认证。简而言之,就是需要在setting文件中配置server元素,其id与仓库的id匹配,并配置正确的认证信息。

  镜像

  如果仓库x可以提供仓库y存储的所有内容,那我们可以说x是y的镜像,典型的事例是,很多国外的服务在中国都有中国的镜像,这样的目的是能够提供更快的服务。

<settings>
         ...
         <mirrors>
                  <mirror>
                          <id>maven.net.cn</id>
                          <name>one of the central mirror in China</name>
                          <url>http://maven.net.cn/content/groups/public</url>
                          <mirrorOf>central</mirrorOf>
                  </mirror>
         </mirrors>
</settings>

  以上就是配置的就是中央仓库在中国的镜像。

  镜像更为常见的是结合私服的使用,由于私服可以代理任何外部的公共仓库,因此,对于组织内部的Maven用户来说,使用一个私服地址,就相当于使用了所有需要的外部仓库,这可以将配置集中到私服,从而简化Maven本身的配置,在这种情况下,任何需要的构件都可以从私服获得,私服就是所有仓库的镜像,这时可以如此配置:

<settings>
         ...
         <mirrors>
                  <mirror>
                          <id>internal repository</id>
                          <name>internal repository manager</name>
                          <url>http://192.168.2.11:1521/maven2/</url>
                          <mirrorOf>*</mirrorOf>
                  </mirror>
         </mirrors>
</settings>

  mirrorOf元素的值为*代表该配置是所有仓库的镜像,任何对于远程仓库的请求都会被转至http://192.168.2.11:1521/maven2/

  Maven还支持其他高级的镜像配置:

  <mirrorOf>*</mirrorOf>

  <mirrorOf>external:*</mirrorOf>匹配所有不在本机上的远程仓库

  <mirrorOf> repo1,repo2</mirrorOf>匹配仓库repo1,repo2

  <mirrorOf> *,!repo2</mirrorOf>匹配所有仓库,repo2除外

  需要注意的是,由于镜像仓库完全屏蔽掉被镜像仓库,当镜像仓库不稳定或者停止服务的时候, Maven仍将无法访问被镜像仓库,因而无法下载构件。