1 何为Maven仓库
- 任何一个依赖、插件或者项目构建的输出都可以称为构件
- 任何一个构件都有一组坐标唯一标识
- Maven可以在某个位置统一存储所有Maven项目共享的构件,这个统一的位置就是仓库
2 仓库的布局
构件:groupId = org.testng、artifactId = testng、version = 5.8、classifier = jdk15、packaging = jar,其对应的路径按如下步骤生成
- 基于构件的groupId准备路径,将groupId中的句号分隔符转换成路径分隔符。该例中,org.testng转换成org/testng/
- 基于构件的artifactId准备路径,也就是在前面的基础上加上artifactId以及一个路径分隔符。这一步过后,路径变成了org/testng/testng/
- 使用版本信息。路径变成了org/testng/testng/5.8/
- 依次加上artifactId,构件分隔符连字号以及version,于是路径变成了org/testng/testng/5.8/testng-5.8
- 如果构件有classifier,就加上构件分隔符和classsifier,路径就变成了org/testng/testng/5.8/testng-5.8-jdk5
- 检查构件的extension,如果存在,则加上句号分隔符和extension,因此路径变成了org/testng/testng/5.8/testng-5.8.jar
Maven仓库是基于简单文件系统存储的
3 仓库的分类
仓库分为两类:本地仓库和远程仓库。当Maven根据坐标寻找构件的时候,首先会查看本地仓库,如果本地仓库存在此构件,则直接使用;如果不存在或者需要查看是否有更新的构件版本,Maven就会去远程仓库查找
- 中央仓库是Maven核心自带的远程仓库
- 私服是另一种特殊的远程仓库,为了节约带宽和时间,在局域网内架设一个私有的仓库服务器,用其代理所有外部的远程仓库
3.1 本地仓库
- 每个用户在自己的用户目录下都有一个路径名为**.m2/repository的仓库目录**
- 用户想自定义本地仓库目录地址,可以编辑文件**~/.m2/settings.xml**,设置localRepository元素的值为想要的仓库地址,如下,F:/Maven/repo就是我的仓库地址
3.2 远程仓库
本地仓库好比书房,需要读书的时候先去书房找,相应的,Maven需要构件的时候先从本地仓库找,远程仓库好比书店,当无法从自己的书房找到需要的书的时候,就回去书店购买后放到书房中,而Maven会从远程仓库下载构件至本地仓库。
每个用户只有一个本地仓库,但可以配置访问很多远程仓库
3.3 中央仓库
- 中央仓库就是Maven默认的、知道的一个可用的远程仓库
- 一个简单的Maven项目需要的依赖构件都能从中央仓库下载到,这也解释了为什么Maven可以做到“开箱即用”
3.4 私服
私服是一种特殊的远程仓库,架设在局域网内的仓库服务,私服代理广域网上的远程仓库,共局域网内的Maven用户使用。当Maven需要下载构件的时候,从私服请求,如果私服上不存在此构件,则从外部的远程仓库下载,缓存在私服上之后,再为Maven的下载请求提供服务。
即使在一台直接连入Internet的个人机器上使用Maven也应该建立私服,私服的优点如下:
- 节省自己的外网带宽
- 加速Maven构建
- 部署第三方构件
- 提高稳定性,增强控制
- 降低中央仓库的负荷
4 远程仓库的配置
<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>
<updatePolicy>daily</updatePolicy>
<checksumPolicy>ignore</checksumPolicy>
</snapshots>
<layout>default</layout>
</repository>
</repositories>
- 在repositories元素下,可以使用repository子元素声明一个或者多个远程仓库。在例子中,声明了一个id为jboss,名称为JBoss Repository的仓库
- 任何一个仓库声明的id必须是唯一的,Maven的中央仓库的id为central
- url的值指向了仓库的地址,该地址都是基于http协议的
- releases和snapshots元素用来控制Maven对于发布版构件和快照版构件的,released的enabled的值为true,表示开启JBoss仓库的发布版本下载支持
- 元素updatePolicy用来配置Maven从远程仓库检查更新的频率,默认值是daily,其他可用值包括:never—从不检查更新;always—每次构建都检查更新;interval:X—每隔X分钟检查一次更新
- 元素checksumPolicy用来配置Maven检查检验和文件的策略。默认值为warn,在执行构建时输出警告信息,其他可用的值包括:fail—Maven遇到校验和错误就让构建失败;ignore—使Maven完全忽略校验和错误
4.1 远程仓库的认证
在本机settings.xml中配置认证信息,配置一个id为my-proj的仓库配置认证信息
<settings>
...
<servers>
<server>
<id>my-proj</id>
<username>repo-user</username>
<password>repo-pwd</password>
</server>
</servers>
...
</settings>
- Maven使用settings.xml文件中并不显而易见的servers元素及其server子元素配置仓库认证信息
- server元素的id必须与POM中需要认证的repository元素的id完全一致
4.2 部署至远程仓库
可以在POM中使用distributionManagement元素将项目构建部署到远程仓库
<distributionManagement>
<repository>
<id>proj-releases</id>
<name>Proj Releases Repository</name>
<url>http://192.168.1.100/content/repositories/proj-releases</url>
</repository>
<snapshotRepository>
<id>proj-snapshots</id>
<name>Proj Snapshot Repository</name>
<url>http://192.168.1.100/content/repositories/proj-snapshots</url>
</snapshotRepository>
</distributionManagement>
- distributionManagement包含repository和snapshotRepository子元素,前者表示发布版本构件的仓库,后者表示快照版本构件的仓库。这两个元素都需要配置id、name和url,id是该远程仓库的唯一标识,name是为了方便人阅读,关键的url表示该仓库的地址
- 往远程仓库部署构件的时候,需要认证,即6.4.1中所讲的
- 在配置完成后,运行mvn clean deploy就会部署到配置对应的远程仓
5 从仓库解析依赖的机制
依赖解析机制可以概括如下:
- 当依赖的范围是system的时候,Maven直接从本地文件系统解析构件
- 根据依赖坐标计算仓库路径后,尝试直接从本地仓库寻找构件,如果发现相应构件,则解析成功
- 在本地仓库不存在相应构件的情况下,如果依赖的版本是显式的发布版本构件,则遍历所有的远程仓库,发现后,下载并解析使用
- 如果依赖的版本是RELEASE或LATEST,则基于更新策略读取所有远程仓库的元数据,将其与本地仓库的对应元素据合并后,计算出RELEASE或LATEST真实的值,然后基于这个真实的值检查本地和远程仓库
- 如果依赖的版本是SNAPSHOT,则基于更新策略读取所有远程仓库的元数据,将其与本地仓库的对应元素据合并后,得到最新快照版本的值,然后基于该值检查本地仓库,或者从远程仓库下载
- 如果最后解析得到的构件版本是时间戳格式的快照,则复制器时间戳格式的文件至非时间戳格式,并使用该非时间戳格式的构件
只有仓库开启了对于发布版本或者快照版本的支持,即<enabled>元素值为True时,才能访问该仓库的发布版本构件信息
不推荐在依赖中使用LATEST和RELEASE
6 镜像
如果仓库X可以提供仓库Y存储的所有内容,那么就可以认为X是Y的一个镜像,由于地理位置的原因,镜像往往能够提供比中央仓库更快的服务,下面我们演示配置镜像:编辑settings.xml
<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>
- <mirrorOf>的值为central,表示该配置为中央仓库的镜像,任何对于中央仓库的请求都会转至该镜像
镜像更为常见的一个用法是结合私服,任何需要的构件都可以从私服获得,私服就是所有仓库的镜像,配置settings.xml文件
<mirrors>
<mirror>
<id>internal-repository</id>
<name>Internal Repository Manager</name>
<url>http://193.168.1.100/maven2</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
为了满足一些复杂的需求,Maven还支持更高级的镜像配置:
- <mirrorOf>*</mirrorOf>:匹配所有远程仓库
- <mirrorOf>external:*</mirrorOf>:匹配所有远程仓库,使用localhost和file://协议的除外,即匹配所有不在本机上的远程仓库
- <mirrorOf>repo1,repo2</mirrorOf>:匹配仓库repo1和repo2
- <mirrorOf>*,! repo1</mirrorOf>:匹配所有的远程仓库,repo1除外,使用感叹号将仓库从匹配中排除
由于镜像仓库完全屏蔽了被镜像仓库,当镜像仓库不稳定或停止服务的时候,Maven将无法访问被镜像仓库
7 仓库搜索服务
7.1 Sonatype Nexus
- 当前最流行的开源Maven仓库管理软件
- 提供了关键字搜索、类名搜索、坐标搜索、校验和搜索等功能
- 用户可以直接下载相应构件,还可以直接复制已经根据坐标自动生成的XML依赖声明
7.2 Jarvana
- 提供了基于关键字、类名的搜索、构件下载、依赖声明片段
- 还支持浏览构件内部的内容,还提供了便捷的Java文档浏览功能
7.3 MVNbrowser
- 只提供关键字搜索的功能
- 能够告诉用户该构件依赖于其他哪些构件以及该构件被哪些其他构件依赖
7.4 MVNrepository
- 提供基于关键字搜索、依赖声明代码片段、构件下载、依赖与被依赖关系信息、构建所含包信息等功能
- 提供一个简单的图表,显示某个构件各版本间的大小变化