环境: OS X EI Capitan 10.11.2 + JDK 1.8.0_66 + Maven 3.3.9
构件在仓库中的路径为: groupId/artifactId/version/artifactId-version-classifier.packaging。
Maven仓库分为本地仓库和远程仓库这两种,首先从本地仓库去找构件,如果存在,则直接使用;如果不存在,去远程仓库查找,找到后,下载到本地仓库。
如果本地仓库和远程仓库都没有找到需要的构件,Maven会报错。
中央仓库Maven核心自带的远程仓库,默认情况下,当本地仓库没有构件的时候,就会从中央仓库下载。
私服是一种特殊的远程仓库,是假设在局域网内的私有仓库,用其代理所有的远程仓库。
除了中央仓库和私服,还有很多其它公开的远程仓库,比如JBoss Maven 库:http://repository.jboss.org/maven2/。
1. 设置本地仓库
默认情况下,本地仓库指向~/.m2/repository目录。
要指向其它目录,需要修改~/.m2/settings.xml文件,增加如下内容:
<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
2. 私服
私服是指在局域网内部搭建的 repository,它跟 central repository,jboss repository等的区别仅仅在于其 URL 是一个内部网址。
3. 设置远程仓库
远程仓库既可以设置在pom.xml中,也可以设置在settings.xml文件中。
<project>
...
<repositories>
<repository>
<id>jdk14</id>
<name>Repository for JDK 1.4 builds</name>
<url>http://www.myhost.com/maven/jdk14</url>
<layout>default</layout>
<snapshotPolicy>always</snapshotPolicy>
</repository>
</repositories>
...
</project>
(1)仓库的id必须唯一。
(2)releases的enable值为true,表示开启发布版本的下载支持。
(3)snapshots的enable值为false,表示关闭快照版本的下载支持。
(4)layout 表示使用Maven 2 或 3 的布局。
(5)updatePolicy 表示从远程仓库的更新频率,默认是daily,每天检查;never,从不检查;always,每次构建都检查更新;X,每隔X分钟检查一次。
(6)checksumPolicy 表示部署构件时,会同时部署对应的校验文件;下载构件时,会验证校验文件。该值为 warn 时,提示警告;为 fail 时,构建失败;为 ignore 时,忽略错误。
4. 配置远程仓库的认证
远程仓库的认证只能设置在settings.xml文件中。
<servers>
<!-- server
| Specifies the authentication information to use when connecting to a particular server, identified by
| a unique name within the system (referred to by the 'id' attribute below).
|
| NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are
| used together.
|
<server>
<id>deploymentRepo</id>
<username>repouser</username>
<password>repopwd</password>
</server>
-->
<!-- Another sample, using keys to authenticate.
<server>
<id>siteServer</id>
<privateKey>/path/to/private/key</privateKey>
<passphrase>optional; leave empty if not used.</passphrase>
</server>
-->
</servers>
5. 部署构件到远程仓库
在pom.xml中设置远程仓库:
<distributionManagement>
<repository>
<id>releases</id>
<name>Nexus Release Repository</name>
<url>http://localhost:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>Nexus Snapshot Repository</name>
<url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
(1)releases 是发布版本的构件,项目外部的依赖应该都是发布版本的构件。
(2)snapshots 是快照版本的构件,快照版本的构件只应该用于项目内部的模块依赖。
(3)repository 中的 id 必须与 server 中的 id 一致。
运行 mvn clean deploy,部署构件到远程仓库,发布版本会部署到发布版本的远程仓库;快照版本会部署到快照版本的远程仓库。
6. 镜像
仓库 X 能够提供仓库 Y 的所有内容,那么仓库 X 就是仓库 Y 的一个镜像。
配置镜像后,本来需要从仓库 Y 下载构件的请求会转到仓库 X。
在 settings.xml 中增加镜像的配置:
例1:指定仓库的镜像
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
</mirrors>
说明:
(1)mirrorOf 指定镜像的repositoryId。也可以以逗号间隔,指定多个远程库。
例2:中央仓库的镜像
<settings>
...
<mirrors>
<mirror>
<id>maven.net.cn</id>
<name>one of the central mirrors in china</name>
<url>http://maven.net.cn/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
...
</settings>
说明:
(1)mirrorOf 指定镜像的repositoryId,这里 central 表示中央仓库。也可以以逗号间隔,指定多个远程库。
例3:所有仓库的镜像
关于镜像的一个更为常见的用法是结合私服。由于私服可以代理任何外部的公共仓库,因此,对于组织内部的 Maven 用户来说,使用一个私服地址就等于使用了所有需要的外部仓库,这可以将配置集中到私服,从而简化 Maven 本身的配置。在这种情况下,任何需要的构件都可以从私服获得,私服就是所有仓库的镜像。
<settings>
...
<mirrors>
<mirror>
<id>internal-repository</id>
<name>Internal Repository Manager</name>
<url>http://192.168.1.100/maven2</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
...
</settings>
说明:
(1) <mirrorOf>*</mirrorOf> ,表示该配置是所有 Maven 仓库的镜像,任何对于远程仓库的请求都会被转至 http://192.168.1.100/maven2/。
如果该镜像仓库需要认证,则配置一个 id 为 internal-repository 的 <server> 即可。
(2) <mirrorOf>external:*</mirrorOf> ,表示匹配所有远程仓库,使用localhost 的除外,使用 file:// 协议的除外。也就是说,匹配所有不在本机上的远程仓库。
(3) <mirrorOf>repo1,repo2</mirrorOf> ,表示匹配仓库 repo1 和 repo2,使用逗号分隔多个远程仓库。
(4) <mirrorOf>*,!repo1</miiroOf> ,表示匹配所有远程仓库,repo1除外,使用感叹号将仓库从匹配中排除。
需要注意的是,由于镜像仓库完全屏蔽了被镜像仓库,当镜像仓库不稳定或者停止服务的时候,Maven 将无法访问被镜像仓库,因此也将无法下载构件。
7. 私服与镜像的区别
私服本身是一个 repository,可以和其它 repository 一起提供服务,比如它可以用来提供公司内部的 maven 构件。
镜像相当于一个代理,它会拦截去指定的远程 repository 下载构件的请求,然后从自己这里找出构件回送给客户端。镜像本身并不是 repository,它只是远程 repository 的网络加速器,配置镜像的目的一般是出于网速考虑。
可以看出,私服和镜像两个不同的东西。
不过很多私服搭建工具本身也提供镜像服务,比如 Nexus 就可以让同一个 URL 既用作internal repository,又使它成为所有 repository 的 mirror。
参考文献:
1. 《Maven 实战》 徐晓斌著