Maven 仓库

来源:互联网 发布:京东网络推广 编辑:程序博客网 时间:2024/05/20 16:44

前面我讲到为什么要使用 Maven, Maven 的安装,以及 如何与 IDE 集成等,前面的介绍可以认为是一个 Hello World,教你如何利用 Maven 来进行项目开发,如何结合 IDE 实现一键式 DEBUG ,从现在开始我们开始深入探讨 Maven 的一些高级内容。

这一个章节,我分两部分来介绍,首先介绍一下 Maven 的仓库,然后在说一下如何通过 Nexus 来建立我们自己的仓库,以及如何使用。

Maven 仓库

在以前使用 Ant 的时候,我们会建立一个 lib 目录在存放我们的 jar 包,比如项目所依赖的第三方包,每建立一个项目都要建立一个 lib ,不停的做 copy 工作,不仅是对于磁盘的浪费,而且也造成了版本管理上的麻烦。而且我们还需要通过提交到 svn 上来对 lib 进行管理,但是 svn 对于这种二进制文件的管理并不出色。

Maven 仓库的初中就是为了解决这个问题,是所有常用的第三方包的集中营。这样所有的 Maven 项目就可以从这个仓库中获取所需要的资源, Maven 仓库中对 jar 通过 Group Id, Atifact Id, version 来管理 ,所以 Maven 项目可以很方便的进行依赖管理。你不需要自己来管理这个庞大的资源仓库,当然你可以创建一个公司层面的仓库管理器,这个我在这个章节的后面会介绍。

Maven 仓库的两个概念:本地仓库和远程仓库

本地仓库是远程仓库的一个缓冲和子集,当你构建 Maven 项目的时候,首先会从本地仓库查找资源,如果没有,那么Maven 会从远程仓库下载到你本地仓库。这样在你下次使用的时候就不需要从远程下载了。如果 你所需要的 jar 包版本在本地仓库没有,而且也不存在于远程仓库, Maven 在构建的时候会报错,这种情况可能发生在有些 jar 包的新版本没有在Maven 仓库中及时更新。

Maven 缺省的本地仓库地址为 ${user.home}/.m2/repository 。也就是说,一个用户会对应的拥有一个本地仓库。当然你可以通过修改 ${user.home}/.m2/settings.xml 配置这个地址:

Xml代码

  1. <settings>
  2.  ...
  3.  <localRepository> D:/java/repository </localRepository>
  4.  ...
  5. </settings>

如果你想让所有的用户使用统一的配置那么你可以修改 Maven 主目录下的 setting.xml:

${M2_HOME}/conf/setting.xml

还可以通过在运行时指定目录,但是并不推荐这么做:

mvn clean install -Dmaven.repo.local=/home/juven/myrepo/

当我们创建一个简单的 Maven 项目后 ( 只需要在 pom.xml 配置好依赖 ) ,运行 mvn clean install 就可以把项目构建好,不需要我们手工下载任何 jar ,这全靠中央仓库的存在,它会自动从仓库下载。这个仓库的定义是在 ${M2_HOME}/lib/maven-2.0.10-uber.jar 里面。你可以在里面找到 /org/apache/maven/project/pom-4.0.0.xml 这个文件,在这个文件里面定义了中央仓库的地址:

  1. <repositories>
  2.  <repository>
  3.  <id> central </id>
  4.  <name> Maven Repository Switchboard </name>
  5.  <layout> default </layout>
  6.  <url> http://repo1.maven.org/maven2 </url>
  7.  <snapshots>
  8.  <enabled> false </enabled>
  9.  </snapshots>
  10.  </repository>
  11. </repositories>

 POM 中配置远程仓库

下面我介绍下如何在 pom.xml 里面配置远程仓库,我们需要在什么时候配置远程仓库呢?当你连接中央仓库的速度比较慢时,或者你为你的公司搭建了自己的仓库,比如 Nexus 仓库管理 ( 后面我会介绍 ) ,又或者你苏需要的 jar 存在另外一个公共仓库,比如我们配置一个国内的镜像地址:

  1. <project>
  2. ...
  3.  <repositories>
  4.  <repository>
  5.  <id> maven-net-cn </id>
  6.  <name> Maven China Mirror </name>
  7.  <url> http://maven.net.cn/content/groups/public/ </url>
  8.  <releases>
  9.  <enabled> true </enabled>
  10.  </releases>
  11.  <snapshots>
  12.  <enabled> false </enabled>
  13.  </snapshots>
  14.  </repository>
  15.  </repositories>
  16.  <pluginRepositories>
  17.  <pluginRepository>
  18.  <id> maven-net-cn </id>
  19.  <name> Maven China Mirror </name>
  20.  <url> http://maven.net.cn/content/groups/public/ </url>
  21.  <releases>
  22.  <enabled> true </enabled>
  23.  </releases>
  24.  <snapshots>
  25.  <enabled> false </enabled>
  26.  </snapshots>
  27.  </pluginRepository>
  28.  </pluginRepositories>
  29. ...
  30. </project>

这里我们可以看到 ,允许配置多个 repository  plugin repository  < releases><enabled>true</enabled></releases> 告诉Maven 可以从这个仓库下载 releases 版本的构件,而 <snapshots><enabled>false</enabled></snapshots> 告诉 Maven 不要从这个仓库下载 snapshot 版本的构件 , 之所以不让你从这个仓库下载 snapshot 版本,是因为这些版本是不稳定的,但是snapshot 版本在我们内部项目开发的时候可是作用巨大,后面的问文章我会讨论这个问题。 至于 <pluginRepositories> ,这是配置 Maven 从什么地方下载插件构件, Maven 的所有行为都是通过插件来完成的,其内部配置与 < repository > 类似,这里就不多说了。

尽管 pom.xml 中可以方便的哦配置中央仓库,但是我并不推荐大家这么做,尤其是在大的公司中,因为一个公司会有很多的项目,如果每个项目都这样配置,那么又开始做重复的 copy 工作了,如何解决呢,我们往下走

 settings.xml 中配置远程仓库

P om.xml 的作用范围是一个项目,一个公司不可能只做一个项目,那么为了避免重复配置,那么我们需要把一些公共信息配置在 setting.xml 中。但是 setting.xml 中并不支持 <repositories>  <pluginRepositories > ,为了解决这个问题我们使用profile 

  1. <settings>
  2.  ...
  3.  <profiles>
  4.  <profile>
  5.  <id> myProfiel </id>
  6.  <!—在这里加入 <repositories>  <pluginRepositories > -->
  7.  </profile>
  8.  </profiles>
  9.  <activeProfiles>
  10.  <activeProfile> myProfiel </activeProfile>
  11.  </activeProfiles>
  12.  ...
  13. </settings>

这里通过 <activeProfile> 元素来激活这个 profile ,这样我们就可以全局的使用这个配置,不再需要为每个 POM 做重复的配置了。

在实际的操作过程中,这里我们最好不要配置远程仓库,最好能够通过 nexus 建立公司或者组织自己的仓库,然后这把把地址指向自己的仓库,后面我会介绍为什么要这么做,怎么做。

配置镜像

如果你想覆盖中央仓库的默认地址,那么这里我们就会使用的镜像了,还在 setting.xml 里面配置:

  1. <settings>
  2. ...
  3.  <mirrors>
  4.  <mirror>
  5.  <id> maven-net-cn </id>
  6.  <name> Maven China Mirror </name>
  7.  <url> http://maven.net.cn/content/groups/public/ </url>
  8.  <mirrorOf> central </mirrorOf>
  9.  </mirror>
  10.  </mirrors>
  11. ...
  12. </settings>

这里解释一下 <mirrorOf>, 表示只为 central 仓库做镜像,如果想为所有的仓库做镜像那么可以改为: <mirrorOf>*</mirrorOf>

如果你看到这里,请先不要着急,实际的项目经验告诉我,只是这些还不够,我们需要更快捷和高效的管理:

利用 Nexus 来构建企业级 Maven 仓库

Nex u s 简介

Nexus  Maven 仓库管理器,用来搭建一个本地仓库服务器,这样做的好处是便于管理,节省网络资源,速度快,还有一个非常有用的功能就是可以通过项目的 SNAPSHOT 版本管理,来进行模块间的高效依赖开发,下面会一一描述。

虽然你可以通过中央仓库来获取你所需要的 jar 包,但是现实往往是存在很多问题:

  1. 网速慢,你可能需要花很长的时间来下载你所需要的 jar
  2. 如果你的公司很大,有几百甚至几千人再用 Maven ,那么这些人都去通过中央仓库来获取 jar ,那么这是一个很大的资源浪费
  3. 如果存在模块之间的依赖开发,你的 snapshot 版本是不能够被你的伙伴很方便的获取。
  4. 在实际开发过程中,有些 jar 的版本可能在中央仓库里面不存在,或者更新不及时 ,你是获取不到这个 jar 的。

所有以上问题,通过 Nexus 这个日益流行的仓库管理器可以轻松的解决。

    1. 这个仓库是本地的,下载的速度是从远程下载不可比的。
    2. 可以为你公司所有的 Maven 使用者服务,可以进行统一管理
    3. 后面我会介绍如何通过 nexus 来进行存在模块依赖的项目的开发
    4. 你可以添加自己的第三方包。

安装 Nexus

我们从 http://nexus.sonatype.org/downloads/ 来获取最新版本,目前最新版本为 1.3.4

Nexus 提供了两种安装方式,一种是内嵌 Jetty  bundle ,只要你有 JRE 就能直接运行。第二种方式是 WAR ,你只须简单的将其发布到 web 容器中即可使用。

1  Bundle 方式安装

解压 nexus-webapp-1.3. 4 -bundle.zip 至任意目录,如 D:/ tools  转到 目录 D:/ tools/nexus-webapp-1.3.4 /bin/jsw/windows-x86-32 ,运行 Nexus.bat ,如果你是在 linux下安装,那么就下载 nexus-webapp-1.3. 4 -bundle. tar .gz, 解压后转到${NEXUS_HOME}/ nexus-webapp-1.3.3/bin/jsw/linux-x86-32 ,它还支持solaris,macos等操作系统 。当你看到“Started SelectChannelConnector@0.0.0.0:8081”之后,说明Nexus启动成功了,然后打开浏览器,访问http://127.0.0.1:8081/nexus, 通过admin的帐号 (admin)和密码(admin123)登录 你会看到如下的页面:

如果有新版本发布,会有提示在默认页面上。

这里,可以管理仓库,配置 Nexus 系统,管理任务,管理用户,角色,权限,查看系统的 RSS 源,管理及查看系统日志,等等。

War 方式安装

你可以同过 war 的方式以 web 应用的形式发布到你的应用服务器,比如 tomcat 。你所要做的就是下载 war 版本的文件,然后放到应用服务器的发布目录即可,这里就不多讲了。

到此我们已经安装好 Nexus, 下面我来介绍下一些我们常用的功能和使用:

配置 中央仓库

先看一下界面:

在左边菜单栏里选择 Repositories ,然后会出现右边的画面,右边上半部分是列出来的 repository ,黑体字是类型为group  repository. 这里简单介绍下几种 repository 的类型 :

  • hosted,本地仓库,通常我们会部署自己的构件到这一类型的仓库。 比如公司的第二方库 
  • proxy,代理仓库,它们被用来代理远程的公共仓库,如maven中央仓库。
  • group,仓库组,用来合并多个hosted/proxy仓库, 当你的项目希望在多个 repository使用资源时就不需要多次引用了,只需要引用一个group即可。

Maven central是Maven的中央仓库,点击它并选择configuration标签栏,我们会看到下面的页面:

这里有几个项目是我们可能会经常用到的:

  1. Override local storage location: 在这个选项你可以配置你的 Nexus 本地仓库的存放地址 ,用来覆盖其默认的存放地址
  2. Remote storage location: 这里是远程仓库的地址,为了提高代理速度,你可以修改为国内的镜像地址。默认值是http://repo1.maven.org/maven2/
  3. Download remote indexes: 这里配置是否下载远程索引文件,模式是 false, 建议配置为 true ,这样我们便可以通过索引文件来搜索我们需要的构件。

添加代理仓库

Maven central 是一个比较大的代理仓库,如果你需要添加的一个代理仓库,那么可以在 点击左边惨淡栏里面的Repositories, 然后右边的页面点击 add -> add proxy repository, 之后出现以下页面:

填写相关信息保存即可。 通常情况下 , 使用预设的代理仓库已经能够满足大部分项目的需求了 只有在特殊需求的情况下才会参加代理仓库 .

管理本地仓库

我们前面讲到类型为 hosted 的为本地仓库, Nexus 预定义了 3 个本地仓库,分别是 Releases, Snapshots, 3 rd Party. 分别讲一下这三个预置的仓库都是做什么用的 :

  1. Releases: 这里存放我们自己项目中发布的构建 通常是 Release 版本的 比如我们自己做了一个 FTP Server 的项目 生成的构件为 ftpserver.war, 我们就可以把这个构建发布到 Nexus  Releases 本地仓库 关于符合发布后面会有介绍 .
  2. Snapshots: 这个仓库非常的有用 它的目的是让我们可以发布那些非 release 版本 非稳定版本 比如我们在 trunk 下开发一个项目 , 在正式 release 之前你可能需要临时发布一个版本给你的同伴使用 因为你的同伴正在依赖你的模块开发那么这个时候我们就可以发布 Snapshot 版本到这个仓库 你的同伴就可以通过简单的命令来获取和使用这个临时版本 .
  3. 3 rd Party: 顾名思义 第三方库 你可能会问不是有中央仓库来管理第三方库嘛 没错 这里的是指可以让你添加自己的第三方库 比如有些构件在中央仓库是不存在的 比如你在中央仓库找不到 Oracle  JDBC 驱动 这个时候我们就需要自己添加到 3rd party 仓库 .
  4. 你也可以创建自己的本地仓库,点击 Repository 面板上方的 Add 按钮,然后选择 Hosted Repository ,然后在下方的配置面板中输入相关信息 这里我们不再需要填写远程仓库地址,根据自己的需要选择 Release 或者 Snapshot ,如图:

Maven 仓库组

仓库组的概念是 Maven 没有的 , 通过前面介绍可以了解到 我们可以建立多个 proxy 代理仓库 ,hosted 本地仓库 如果没有仓库组的概念 , 我们如果需要引用这些仓库的是时候需要一一加入到我们的 setting.xml 里面去 有了仓库的组的概念 我们只需要做一次引用就可以了 , 把我们需要的仓库加入到仓库组即可 . 像这样 :

<repositories>

<repository>

<id>nexus</id>

<url>http:// 127.0.0.1 :8081/nexus/content/groups/public/</url>

<releases>

<enabled>true</enabled>

</releases>

<snapshots>

<enabled>true</enabled>

</snapshots>

</repository>

</repositories>

Nexus 中预设了 2 个仓库组 , public repositories  public snapshot repositories. 如图 :

这个仓库组默认包含本地仓库 Releases, snapshots, 3 rd party 和代理仓库 Maven Central. 你可以在 Configuration 配置页添加仓库到这个仓库组 . 如果需要你还可以创建一个仓库组 , 如图 :

点击 Add->Repository Group

出现 New Repository Group 界面后 , 填入 ID, name 等相关信息 在右边 Available Repositories 栏里可以选择你要添加的仓库 到你 新建的仓库组 .

通过 Nexus 搜索构件

在我们实际使用构件的过程中通常遇到一个问题 , 有时候我紧紧知道我所需要的构建的大致名字 , 并不知道全称或group id, 这是件非常头疼的事情 . Nexus 基于 Nexus indexer 的搜索功能帮我们解决了这个问题 .

要是用搜索功能 必须要有索引文件 Nexus 默认是不建立索引文件的 , 因为像中央仓库这样的索引文件的建立需要耗费比较大的网络资源 , 仅索引文件就要几十兆 要开启中央仓库的索引文件下载功能需要在 Maven Central 的配置页面 , Download Remote Indexes 选择 true. 如图 :

这样设置以后 , Nexus 会自动从远程中央仓库下载索引文件 为了检验索引文件自动下载是否生效 , 可以却换到 Browse:

如果出现先以上文件夹 , 那说明索引文件已经建立 .

下面我试一下搜索功能 在左边菜单栏里面有个 Artifact Search, 在输入框里面输入你想要搜索的构件名字 , 比如 :testing 那么查询结果如下:

这是模糊查询的结果,当然如果你知道更多信息,比如版本号等,你可以使用高级搜索,点击高级搜索后,右边界面会提供集中搜索方式: keyword, classname, GAV, checksum

比如我们这里选择 GAV 模式 而且我只知道 artiface name : testng 和版本号 5.8, 其他的我不知道 那么就在 artifact version 处分别输入 testng  5.8 , 搜索结果如下 :

你如果你不知道知道构件的名称 只知道 classname, 那么你也可以通过 class name 的方式搜索 , 这里就不再 赘述

当你选择一项搜索结果 , 在页面的下方会出现这个构件的详细信息 并且会列出这个构件的 Maven 依赖配置 你可以直接拷贝到你的 pom 文件中使用 , 这是个非常实用的功能 :

 Maven 中使用 Nexus

到此为止我们介绍了如何安装和使用 Nexus 以及其基本配置 下面我们介绍下如何让 Maven 来使用 Nexus 本地仓库用来替代使用远程仓库  Maven 使用 Nexus 本地仓库只需稍作配置  settings.xml 中加入以下代码 :

<profile>

<id>dev</id>

<repositories>

<repository>

<id>nexus</id>

<url>http:// 127.0.0.1 :8081/nexus/content/groups/public/</url>

<releases>

<enabled>true</enabled>

</releases>

<snapshots>

<enabled>true</enabled>

</snapshots>

</repository>

</repositories>

<pluginRepositories>

<pluginRepository>

<id>nexus</id>

<url>http://127 . 0.0.1:8081/nexus/content/groups/public</url>

<releases>

<enabled>true</enabled>

</releases>

<snapshots>

<enabled>true</enabled>

</snapshots>

</pluginRepository>

</pluginRepositories>

</profile>

</profiles>

<activeProfiles>

<activeProfile>dev</activeProfile>

</activeProfiles>

这里配置了 repository  pluginRepository, Maven 在使用第三方构件和插件时是分开来配置的 , 所以如果我们也希望插件的下载也通过我们的本地仓库来下载 , 那么我们就需要配置 pluginRepository.

红色字体部分就是我们之前安装的 Nexus 的地址 这个地址可以是你们公司局域网内部的一台仓库服务器 .

<releases> <enabled>true</enabled></releases> 这个标签的作用是设定是否允许 下载

release 版本  载构件 同样 snapshots 标签可以设定是否允许 下载 snapshot 版本 的构件 .

通常 , 我们不建议下载 snapshot 版本的构件 , 因为它是不稳定的版本 除非你有特殊的需

 .

构件部署

有些时候我们需要部署构件到 Nexus  3rd party, 比如我们在中央仓库找不到我们需要的构件 我们可以通过 Nexus  UI来上传构件 :

点击左边菜单栏的 Repositories, 然后点击右边界面的 3rd party, 选择界面下方的 Artifact Upload, 这个时候出现以下界面 :

上传构件需要两个步骤 , 一个是定义文件的上传 , 再就是构件的实体文件 .

第一部分定义文件可以是 POM 文件 这也是比较推荐的方式 如果没有 pom 文件 , 可以

选择以参数的形式输入 .

第二部分是上传构件的实体文件 , 这里简单说一下 Classifier  Extension, 这两个都是选

填相 , Classifier 用来区别同功能的构件用于不同的场景 比如这个构件是分别针对 JDK14

 JDK15 做了 2 个功能一样的 Jar, 这个时候你就需要指定这个构件的 Classifier  JDK14

还是 JDK15. Extension 是指扩展名 , 如果不提供 , 那么会自动取这个构件的 Packaging Type

作为扩展名 比如 ear, jar, war 等等 . (Packaging Type 是在第一步中通过 pom 文件或者手

工输入得到的 )

刚才说了 3rd party 的部署 关于 releases  snapshots  UI 部署也是一样的操作过程 .

我们之前也讲过 这里的 releases  snapshots 是用来部署我们自己的项目构件的 通过

UI 部署是可以 , 但是不是最高效的 我们可以通过配置 Maven 来自动部署我们的项目构

 , 这也是我们建立自己的仓库的一个非常重要的原因 下面就让我们看看如何配置 :

首先需要在 POM 文件中加入以下代码 :

  1. <project>
  2. ...
  3. <distributionManagement>
  4.  <repository>
  5.  <id> nexus-releases </id>
  6.  <name> Nexus Release Repository </name>
  7.  <url> http://127.0.0.1:8081 /nexus/content/repositories/releases/ </url>
  8.  </repository>
  9.  <snapshotRepository>
  10.  <id> nexus-snapshots </id>
  11.  <name> Nexus Snapshot Repository </name>
  12.  <url> http://127.0.0.1:8081 /nexus/content/repositories/snapshots/ </url>
  13.  </snapshotRepository>
  14. </distributionManagement>
  15. ...
  16. </project>

这里配置 ,  Maven 知道当我要发布 release 版本或者 snapshot 版本是需要发布到哪个地址 .

然后我们需要在 setting.xml 里面配置一下 Nexus 的帐号和密码 :

  1. <settings>
  2. ...
  3. <servers>
  4.  <server>
  5.  <id> nexus-releases </id>
  6.  <username> admin </username>
  7.  <password> admin123 </password>
  8.  </server>
  9.  <server>
  10.  <id> nexus-snapshots </id>
  11.  <username> admin </username>
  12.  <password> admin123 </password>
  13.  </server>
  14. </servers>
  15. ...
  16. </settings>

到此为止 我们就可以通过命令 mvn deploy 或者通过 IDE 的可视化界面点击 deploy 来发布我们项目到本地仓库了 通过这种方式我们可以很方便的进行模块间的依赖开发 在后面的文章中我会详细介绍如何通过 snapshot 来让我们的依赖开发变得简单 .

小结

本文介绍了 Maven 仓库 如何通过 Nexus 建立自己本地仓库 通过和远程仓库的比较 我们知道 Nexus 给我带来很多方便之处 方便我们管理 方便我们的项目构件部署 项目的依赖开发等 还在等什么 创建你自己的仓库吧 .

Maven详解之仓库------本地仓库、远程仓库

分类: 开发环境与管理工具 maven配置详解 3204人阅读 评论(0) 收藏 举报
maven仓库maven快照远程仓库本地仓库私服

在Maven中,任何一个依赖、插件或者项目构建的输出,都可以称之为构件。

Maven在某个统一的位置存储所有项目的共享的构件,这个统一的位置,我们就称之为仓库。(仓库就是存放依赖和插件的地方)

任何的构件都有唯一的坐标,Maven根据这个坐标定义了构件在仓库中的唯一存储路径,

解读Maven在仓库中的存储路径:

1.基于groupId准备路径,将句点分隔符转成路径分隔符,就是将  "."  转换成 "/" ; example: org.testng --->org/testng

2.基于artifactId准备路径,将artifactId连接到后面:org/testng/testng

3.使用version准备路径,将version连接到后面:org/testng/testng/5.8

4.将artifactId于version以分隔符连字号连接到后面:org/testng/testng/5.8/tesng-5.8

5.判断如果构件有classifier,就要在 第4项 后增加 分隔符连字号 再加上 classifier,org/testng/testng/5.8/tesng-5.8-jdk5

6.检查构件的extension,如果extension存在,则加上句点分隔符和extension,而extension是由packing决定的,org/testng/testng/5.8/tesng-5.8-jdk5.jar

到这里我们就明白了Maven 对于构件存储的细节。

Maven 仓库的分类:

maven的仓库只有两大类:1.本地仓库 2.远程仓库,在远程仓库中又分成了3种:2.1 中央仓库 2.2 私服 2.3 其它公共库

1.本地仓库,顾名思义,就是Maven在本地存储构件的地方。

注:maven的本地仓库,在安装maven后并不会创建,它是在第一次执行maven命令的时候才被创建

maven本地仓库的默认位置:无论是Windows还是Linux,在用户的目录下都有一个.m2/repository/的仓库目录,这就是Maven仓库的默认位置

如何更改maven默认的本地仓库的位置:这里要引入一个新的元素:localRepository,它是存在于maven的settings.xml文件中

1.1 更改配置用户范围的本地仓库:先在/.m2/目录下创建settings.xml文件,然后在~/.m2/settings.xml,设置localRepository元素的值为想要的仓库地址

[html] view plaincopy
  1. <settings>  
  2.     <localRepository>D:\maven_new_repository</localRepository>  
  3. </settings>  
这时候,maven的本地仓库地址就变成了 D:\maven_new_repository ,注:此时配置的maven的本地仓库是属于用户范围的。

1.2 更改配置全局范围的本地仓库:在M2_HOME/conf/settings.xml中更改配置,更改配置的方法同上

注:此时更改后,所有的用户都会受到影响,而且如果maven进行升级,那么所有的配置都会被清除,所以要提前复制和备份M2_HOME/conf/settings.xml文件

故:一般情况下不推荐配置全局的settings.xml

2. 远程仓库

2.1 说到远程仓库先从 最核心的中央仓库开始,中央仓库是默认的远程仓库,maven在安装的时候,自带的就是中央仓库的配置

在maven的聚合与继承中我们说过,所有的maven项目都会继承超级pom,具体的说,包含了下面配置的pom我们就称之为超级pom

[html] view plaincopy
  1. <repositories>  
  2.     <repository>  
  3.       <id>central</id>  
  4.       <name>Central Repository</name>  
  5.       <url>http://repo.maven.apache.org/maven2</url>  
  6.       <layout>default</layout>  
  7.       <snapshots>  
  8.         <enabled>false</enabled>  
  9.       </snapshots>  
  10.     </repository>  
  11.   </repositories>  
中央仓库包含了绝大多数流行的开源Java构件,以及源码、作者信息、SCM、信息、许可证信息等。一般来说,简单的Java项目依赖的构件都可以在这里下载到

2.2 私服

私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用。当Maven需要下载构件的时候,它从私服请求,如果私服上不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为Maven的下载请求提供服务。我们还可以把一些无法从外部仓库下载到的构件上传到私服上。

Maven私服的 个特性:

1.节省自己的外网带宽:减少重复请求造成的外网带宽消耗

2.加速Maven构件:如果项目配置了很多外部远程仓库的时候,构建速度就会大大降低

3.部署第三方构件:有些构件无法从外部仓库获得的时候,我们可以把这些构件部署到内部仓库(私服)中,供内部maven项目使用

4.提高稳定性,增强控制:Internet不稳定的时候,maven构建也会变的不稳定,一些私服软件还提供了其他的功能

5.降低中央仓库的负荷:maven中央仓库被请求的数量是巨大的,配置私服也可以大大降低中央仓库的压力

当前主流的maven私服:

1.Apache的Archiva

2.JFrog的Artifactory

3.Sonatype的Nexus

三、远程仓库配置

配置远程仓库将引入新的配置元素:<repositories>     <repository>

<repositories>元素下,可以使用  <repository>子元素声明一个或者多个远程仓库。

例子:

[html] view plaincopy
  1. <repositories>  
  2.         <repository>  
  3.             <id>jboss</id>  
  4.             <name>JBoss Repository</name>  
  5.             <url>http://repository.jboss.com/maven2/</url>  
  6.             <releases>  
  7.                 <updatePolicy>daily</updatePolicy><!-- never,always,interval n -->  
  8.                 <enabled>true</enabled>  
  9.                 <checksumPolicy>warn</checksumPolicy><!-- fail,ignore -->  
  10.             </releases>  
  11.             <snapshots>  
  12.                 <enabled>false</enabled>  
  13.             </snapshots>  
  14.             <layout>default</layout>  
  15.         </repository>  
  16.     </repositories>  
<updatePolicy>元素:表示更新的频率,值有:never, always,interval,daily, daily 为默认值

<checksumPolicy>元素:表示maven检查和检验文件的策略,warn为默认值

出于安全方面的考虑,有时我们要对远程仓库的访问进行认证,一般将认证信息配置在settings.xml中:

[html] view plaincopy
  1. <span style="white-space:pre">    </span><servers>  
  2.         <server>  
  3.             <id>same with repository id in pom</id>  
  4.             <username>username</username>  
  5.             <password>pwd</password>  
  6.         </server>  
  7.     </servers>  
注:这里的id必须与POM中需要认证的repository元素的Id一致。


如何将生成的项目部署到远程仓库

完成这项工作,也需要在POM中进行配置,这里有新引入了一个元素:<distributionManagement>

distributionManagement包含了2个子元素:repository和snapshotRepository, 前者表示发布版本构件的仓库,后者表示快照版本的仓库

这两个元素都需要配置 id(该远程仓库的唯一标识),name,url(表示该仓库的地址)

向远程仓库中部署构件,需要进行认证。配置同上

配置正确后运行: mvn clean deploy

正确的看待快照

之前我们在配置pom的时候,对于快照的配置都很谨慎,或者说很少用快照的版本,原因是它还很不稳定,极容易给我们的系统带来未知的错误,让我们很难查找。其实快照版本也并不是一无是处,快照最大的用途是用在开发的过程中,尤其是有模块依赖的时候,比如说AB两个模块同时开发,A依赖于B,开发过程中AB都是持续集成的开发,不断的修改POM文件和构建工程,这时候版本同步就成了一个很大的问题。使用快照就可以达到这一目的。

其实在快照版本在发布的过程中,Maven会自动为构件以当前时间戳做标记,有了这个时间戳,我们就可以随时找到最新的快照版本,这样也就解决刚才说的 协作开发的问题。

至于A如何检查B的更新,刚刚在讲配置的时候说过,快照配置中有一个元素可以控制检查更新的频率------updatePolicy

我们也可以使用命令行加参数的形式强制执行让maven检查更新:

mvn clean install-U


maven到底是如何从仓库中解析构件的呢?----maven从仓库解析依赖的机制

1. 当依赖的范围是system的时候,Maven直接从本地文件系统解析构件

2. 根据依赖坐标计算仓库路径后,尝试直接从本地仓库寻找构件,如果发现相应构件,则解析成功

3. 在本地仓库不存在相应的构件情况下,如果依赖的版本是显示的发布版本构件,则遍历所有的远程仓库,发现后下载使用

4. 如果依赖的版本是RELEASE或LATEST, 则基于更新策略读取所有远程仓库的元数据,将其于本地仓库的对应元数据合并后,计算出RELEASE或者LATEST的真实值,然后基于这个真实值检查本地仓库

5. 如果依赖的版本是SNAPSHOT, 则基于更新策略读取所有远程仓库的元数据, 将其与本地仓库的对应元数据合并后,得到最新快照版本的值,然后基于该值检查本地仓库或从远程仓库下载

6. 如果最后解析到的构件版本是时间戳格式的快照,则复制其时间戳格式的文件 至 非时间戳格式,并使用该非时间戳格式的构件

注:一定要记得<release>  <enabled>     &    <snapshot>  <enabled> ,对于快照也是一样

在POM的依赖声明的时候不推荐使用LATEST & RELEASE, 在Maven3中也不再支持在插件配置中使用LATEST & RELEASE, 如果不设置插件版本,那么最终版本和release一样,

maven只会解析最新的发布版本构建。

1.什么是Maven仓库

在不用Maven的时候,比如说以前我们用Ant构建项目,在项目目录下,往往会看到一个名为/lib的子目录,那里存放着各类第三方依赖jar文件,如log4j.jar,junit.jar等等。

每建立一个项目,你都需要建立这样的一个/lib目录,然后复制一对jar文件,这是很明显的重复。重复永远是噩梦的起点,多个项目不共用相同的jar文件,不仅会造成磁盘资源的浪费,也使得版本的一致性管理变得困难。

此外,如果你使用版本管理工具,如SVN(你没有使用版本管理工具?马上试试SVN吧,它能帮你解决很多头疼的问题),你需要将大量的jar文件提交到代码库里,可是版本管理工具在处理二进制文件方面并不出色。
Maven仓库就是放置所有JAR文件(WAR,ZIP,POM等等)的地方,所有Maven项目可以从同一个Maven仓库中获取自己所需要的依赖JAR,这节省了磁盘资源。此外,由于Maven仓库中所有的JAR都有其自己的坐标,该坐标告诉Maven它的组ID,构件ID,版本,打包方式等等,因此Maven项目可以方便的进行依赖版本管理。你也不在需要提交JAR文件到SCM仓库中,你可以建立一个组织层次的Maven仓库,供所有成员使用。
简言之,Maven仓库能帮助我们管理构件(主要是JAR)。
 

2. 本地仓库 vs. 远程仓库

2.1 本地仓库

运行Maven的时候,Maven所需要的任何构件都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构件至本地仓库,然后再使用本地仓库的构件。
比如说,你的项目配置了junit-3.8的依赖,在你运行mvn test 的时候,Maven需要使用junit-3.8的jar文件,它首先根据坐标查找本地仓库,如果找到,就直接使用。如果没有,Maven会检查可用的远程仓库配置,然后逐个尝试这些远程仓库去下载junit-3.8的jar文件,如果远程仓库存在该文件,Maven会将其下载到本地仓库中,继而使用。如果尝试过所有远程仓库之后,Maven还是没能够下载到该文件,它就会报错。
Maven缺省的本地仓库地址为${user.home}/.m2/repository 。也就是说,一个用户会对应的拥有一个本地仓库。
你也可以自定义本地仓库的位置,修改${user.home}/.m2/settings.xml :

1<settings>
2  ...
3  <localRepository>D:/java/repository</localRepository>
4  ...
5</settings>

你还可以在运行时指定本地仓库位置:

1mvn clean install -Dmaven.repo.local=/home/juven/myrepo/

 
还有一点需要理解的是,当我们运行install的时候,Maven实际上是将项目生成的构件安装到了本地仓库,也就是说,只有install了之后,其它项目才能使用此项目生成的构件。

2.2 远程仓库

了解了本地仓库,接着了解一下Maven缺省的远程仓库,即Maven中央仓库。
安装好Maven之后,我们可以建立一个简单的项目,配置一些简单的依赖,然后运行mvn clean install,项目就构建好了。我们没有手工的去下载任何jar文件,这一切都是因为Maven中央仓库的存在,当Maven在本地仓库找不到需要的jar文件时,它会查找远程仓库,而一个原始的Maven安装就自带了一个远程仓库——Maven中央仓库。
这个Maven中央仓库是在哪里定义的呢?在我的机器上,我安装了maven-2.0.10,我可以找到这个文件:${M2_HOME}/lib/maven-2.0.10-uber.jar ,打开该文件,能找到超级POM:/org/apache/maven/project/pom-4.0.0.xml ,它是所有Maven POM的父POM,所有Maven项目继承该配置,你可以在这个POM中发现如下配置:

01<repositories>
02  <repository>
03    <id>central</id>
04    <name>Maven Repository Switchboard</name>
05    <layout>default</layout>
06    <url>http://repo1.maven.org/maven2</url>
07    <snapshots>
08      <enabled>false</enabled>
09    </snapshots>
10  </repository>
11</repositories>

 关于远程仓库的配置,下面的小节我会详细解释,这里我们只要知道,中央仓库的id为central,远程url地址为http://repo1.maven.org/maven2,它关闭了snapshot版本构件下载的支持。

3. 配置远程仓库

3.1. 在POM中配置远程仓库

前面我们看到超级POM配置了ID为central的远程仓库,我们可以在POM中配置其它的远程仓库。这样做的原因有很多,比如你有一个局域网的远程仓库,使用该仓库能大大提高下载速度,继而提高构建速度,也有可能你依赖的一个jar在central中找不到,它只存在于某个特定的公共仓库,这样你也不得不添加那个远程仓库的配置。
这里我配置一个远程仓库指向中央仓库的中国镜像:

01<project>
02...
03  <repositories>
04    <repository>
05      <id>maven-net-cn</id>
06      <name>Maven China Mirror</name>
07      <url>http://maven.net.cn/content/groups/public/</url>
08      <releases>
09        <enabled>true</enabled>
10      </releases>
11      <snapshots>
12        <enabled>false</enabled>
13      </snapshots>
14    </repository>
15  </repositories>
16  <pluginRepositories>
17    <pluginRepository>
18      <id>maven-net-cn</id>
19      <name>Maven China Mirror</name>
20      <url>http://maven.net.cn/content/groups/public/</url>
21      <releases>
22        <enabled>true</enabled>
23      </releases>
24      <snapshots>
25        <enabled>false</enabled>
26      </snapshots>   
27    </pluginRepository>
28  </pluginRepositories>
29...
30</project>

我们先看一下<repositories>的配置,你可以在它下面添加多个<repository> ,每个<repository>都有它唯一的ID,一个描述性的name,以及最重要的,远程仓库的url。

此外,<releases><enabled>true</enabled></releases>告诉Maven可以从这个仓库下载releases版本的构件,而<snapshots><enabled>false</enabled></snapshots>告诉Maven不要从这个仓库下载snapshot版本的构件。禁止从公共仓库下载snapshot构件是推荐的做法,因为这些构件不稳定,且不受你控制,你应该避免使用。当然,如果你想使用局域网内组织内部的仓库,你可以激活snapshot的支持。
关于<repositories>的更详细的配置及相关解释,请参考:http://www.sonatype.com/books/maven-book/reference_zh/apas02s08.html。
至于<pluginRepositories>,这是配置Maven从什么地方下载插件构件(Maven的所有实际行为都由其插件完成)。该元素的内部配置和<repository>完全一样,不再解释。
 

3.2. 在settings.xml中配置远程仓库

我们知道了如何在POM中配置远程仓库,但考虑这样的情况:在一个公司内部,同时进行这3个项目,而且以后随着这几个项目的结束,越来越多的项目会开始;同时,公司内部建立一个Maven仓库。我们统一为所有这些项目配置该仓库,于是不得不为每个项目提供同样的配置。问题出现了,这是重复 !
其实我们可以做到只配置一次,在哪里配置呢?就是settings.xml。
不过事情没有那么简单,不是简单的将POM中的<repositories>及<pluginRepositories>元素复制到settings.xml中就可以,setting.xml不直接支持 这两个元素。但我们还是有一个并不复杂的解决方案,就是利用profile,如下:

01<settings>
02  ...
03  <profiles>
04    <profile>
05      <id>dev</id>
06      <!-- repositories and pluginRepositories here-->
07    </profile>
08  </profiles>
09  <activeProfiles>
10    <activeProfile>dev</activeProfile>
11  </activeProfiles>
12  ...
13</settings>

 
这里我们定义一个id为dev的profile,将所有repositories以及pluginRepositories元素放到这个profile中,然后,使用<activeProfiles>元素自动激活该profile。这样,你就不用再为每个POM重复配置仓库。
使用profile为settings.xml添加仓库提供了一种用户全局范围的仓库配置。

4. 镜像

如果你的地理位置附近有一个速度更快的central镜像,或者你想覆盖central仓库配置,或者你想为所有POM使用唯一的一个远程仓库(这个远程仓库代理的所有必要的其它仓库),你可以使用settings.xml中的mirror配置。 
以下的mirror配置用maven.net.cn覆盖了Maven自带的central:

01<settings>
02...
03  <mirrors>
04    <mirror>
05      <id>maven-net-cn</id>
06      <name>Maven China Mirror</name>
07      <url>http://maven.net.cn/content/groups/public/</url>
08      <mirrorOf>central</mirrorOf>
09    </mirror>
10  </mirrors>
11...
12</settings>

 这里唯一需要解释的是<mirrorOf>,这里我们配置central的镜像,我们也可以配置一个所有仓库的镜像,以保证该镜像是Maven唯一使用的仓库:

01<settings>
02...
03  <mirrors>
04    <mirror>
05      <id>my-org-repo</id>
06      <name>Repository in My Orgnization</name>
07      <url>http://192.168.1.100/maven2</url>
08      <mirrorOf>*</mirrorOf>
09    </mirror>
10  </mirrors>
11...
12</settings>

 
关于更加高级的镜像配置,可以参考:http://maven.apache.org/guides/mini/guide-mirror-settings.html。
 

5. 分发构件至远程仓库

mvn install 会将项目生成的构件安装到本地Maven仓库,mvn deploy 用来将项目生成的构件分发到远程Maven仓库。本地Maven仓库的构件只能供当前用户使用,在分发到远程Maven仓库之后,所有能访问该仓库的用户都能使用你的构件。
我们需要配置POM的distributionManagement来指定Maven分发构件的位置,如下:

01<project> 
02  ... 
03  <distributionManagement> 
04    <repository> 
05      <id>nexus-releases</id> 
06      <name>Nexus Release Repository</name> 
07      <url>http://127.0.0.1:8080/nexus/content/repositories/releases/</url> 
08    </repository> 
09    <snapshotRepository> 
10      <id>nexus-snapshots</id> 
11      <name>Nexus Snapshot Repository</name> 
12      <url>http://127.0.0.1:8080/nexus/content/repositories/snapshots/</url> 
13    </snapshotRepository> 
14  </distributionManagement> 
15  ... 
16</project>

 
Maven区别对待release版本的构件和snapshot版本的构件,snapshot为开发过程中的版本,实时,但不稳定,release版本则比较稳定。Maven会根据你项目的版本来判断将构件分发到哪个仓库。
一般来说,分发构件到远程仓库需要认证,如果你没有配置任何认证信息,你往往会得到401错误。这个时候,如下在settings.xml中配置认证信息:

01<settings> 
02  ... 
03  <servers> 
04    <server> 
05      <id>nexus-releases</id> 
06      <username>admin</username> 
07      <password>admin123</password> 
08    </server> 
09    <server> 
10      <id>nexus-snapshots</id> 
11      <username>admin</username> 
12      <password>admin123</password> 
13    </server>   
14  </servers> 
15  ... 
16</settings>

 
需要注意的是,settings.xml中server元素下id的值必须与POM中repository或snapshotRepository下id的值完全一致。将认证信息放到settings下而非POM中,是因为POM往往是它人可见的,而settings.xml是本地的。

6. 小结

本文介绍了Maven仓库,它是什么?本地仓库,远程仓库,中央仓库具体是指什么?并介绍了如何在POM中配置项目层次的仓库,在settings中配置用户层次的仓库,以及mirror。本文还介绍了如何安装构件到本地仓库,如何分发构件至仓库。


0 0
原创粉丝点击