仓库
坐标是用来定义其在仓库中的唯一存储路径,这便是Maven的仓库布局方式,例如log4j:log4j:1.2.15,其对应的仓库路径为log4j/log4j/1.2.15/log4j-1.2.15.jar,其实路径与坐标的
大致对应关系为groupId/artifactId/version/artifactId-version.packaging,如果构建有classifier,就加上构建分隔符和classifier,例如classifier是jdk15,那么路径就是:
/org/testing/testing/5.8/testing-5.8-jdk5,检查构建的extension是否存在,则加上句点分隔符和extension,extension是从artifactHandler而非artifact获取,actifactHandler是由项目的
packaging决定的,因此可以说packaging决定了构建的扩展名,如果packaging是jar,那么最终路径就是/org/testing/testing/5.8/testing-5.8-jdk5.jar,其实知道了构建的路径,当遇到
仓库有关的问题,就可以查找相关的文件,当Maven无法获得项目声明的依赖时,可以查看该依赖的文件再仓库是否存在,不存在则查看是否有其他版本可用
仓库分为本地仓库和远程仓库
远程仓库: 中央仓库是Maven核心自带的远程仓库,默认本地仓库没有就会去中央仓库进行下载,私服是另一种特殊的远程仓库,例如在局域网络内架设的仓库服务器,其代理
所有外部的远程仓库,内部的项目还可以部署到私服上供其他项目使用。除了上述两种,还有其他公开的远程仓库,常见的有java.net Maven仓库和JBoss Maven仓库
本地仓库:默认每个用户在自己的目录下都有一个.m2/repository/的仓库目录,有时候如果想要自定义本地仓库目录地址的话,这时可以编辑~/.m2/settings.xml设置localRepository
元素的值为想要的仓库地址,例如<localRepository>D:\java\repository\</localRepository>
每个用户可以配置多个远程仓库而只可以配置一个本地仓库
中央仓库是默认的远程仓库,Maven的安装文件自带了中央仓库的配置,解压工具打开jar文件$M2_HOME/lib/maven-model-builder-3.0.jar 然后访问路径
/org/apache/maven/model/pom-4.0.0.xml可以看到其配置信息 <url>http://repol.maven.org/maven2</url>,包含这段配置的文件是所有Maven项目都会继承的超级POM
最后要注意的是snapshots元素,其子元素enabled的值为false,表示不从该中央库下载快照版本的构建
私服是特殊的远程仓库,他是架设在局域网内的仓库服务,私服代理广域网上的远程仓库,供局域网内的Maven用户使用,当需要下载构建时,它会从私服请求,如果私服
不存在该构件,则从外部的远程仓库下载,缓存在私服上之后,再为Maven的下载请求提供服务,此外,一些无法从外部仓库下载到的构件也能从本地传到私服上供大家使用
私服可以帮助你:
节省自己的外网宽带。在建立了私服代理外部仓库之后,对外的重复构件下载便得以消除,即降低外网宽带的压力
加速Maven构建,不停的连接请求外部仓库很耗时间的,但是Maven的一些内部机制(如快照更新检查)要求Maven在执行构建的时候不停的检查远程仓库数据,因此当配置很多
远程仓库的时候,构建的速度会被大大降低,使用私服可以解决这问题,Maven只需要检查私服的数据时,构建就大大提高了
部署第三方构件,当有的构件无法从远程仓库获得,例如Oracle的JDBC和组织内部的私有构件都无法从远程仓库获得,有了私服后,就可以将这些构件部署到这部内部的仓库中
提高稳定性,增强控制,因为Maven构建高度依赖于远程仓库,当Internet不稳定,则无法顺利构建,但是有了私服后,因为私服中缓存了大量构件,Maven也仍然可以正常运行
此外一些私服软件如Nexus还提供了额外的功能,如权限管理,RELEASE/SNAPSHOT区分等,这样对仓库就有了更高级的控制
降低中央仓库的负荷,在不使用私服的情况下,一个构件往往会被重复下载数百次,建立了私服后,这几百次只会发生在内网范围内,私服对于中央仓库只有一次下载
远程仓库配置,例如JBoss Maven,此时,可以在POM中配置该仓库:<project> <repositories> <repository> <url>JBoss的maven相关地址http://repository.jboss.com/maven2/
repositories元素下可以配置多个远程仓库的repository,但是属性中的ID必须是唯一的,<repository>中配置的releases和snapshots元素比较重要,他们用来控制Maven对于
发布版构件和快照版构件的下载,enabled值为true表示开启下载支持,也就是开启或关闭releases或snapshots的下载支持,
对于releases和snapshots来说,除了enabled外另有两个元素updatePolicy和checksumPolicy:前者是配置Maven从远程仓库检查更新的频率,默认是daily,其他值有never和
always,interval,后者表示Maven检查检验和文件策略,当构件被部署到Maven仓库中时,会同时部署对应的校验和文件,在下载构件的时候,Maven会验证校验和文件,
如果校验和验证失败,当checksumPolicy的默认值是warn时,Maven会在构建时输出警告信息,其他可用的值包括:fail-Maven遇到校验和错误就让构件失败,ignore忽略之意
Maven远程仓库的认证,也就是管理员为每个仓库提供了一组用户名和密码,配置仓库信息和配置认证信息不同,仓库信息可以直接配置在POM文件中,但是认证信息必须
配置在settings.xml文件中,这是因为POM往往是被提交到代码仓库中供所有成员访问的,而settings.xml一般放在本机,在settings.xml中配置认证信息更为安全
配置方式 <settings> <servers> <server> <id>和<username>,<password>,这里的id元素很关键,settings.xml中的server元素的id与POM中需要认证的repository元素id完全一致
部署至远程仓库:私服作用是部署第三方构件和组织内部的构件以及无法从远程仓库获取的构件,Maven除了能进行编译,测试,打包,还能将项目生成的构建部署到仓库中
首先需要编辑项目的pom.xml,配置distributionManagerment元素:其中包含repository和snapshotRepository子元素,前者是发布版本构件的仓库,后者是快照版本的仓库,
这两个元素下都需要配置id,name,url,id为远程仓库唯一标识,name方便阅读,url标识仓库的地址,通常往远程仓库部署构件的时候,往往需要认证,简单说就是需要再
setting.xml中创建一个server元素,其id与仓库的id匹配,并配置正确的认证信息,不论是从远程仓库下载构件还是部署至远程仓库,当需要认证的时候,配置的方式是一样的
配置正确后,执行mvn clean deloy,Maven就将项目输出的构件部署到对应的远程仓库了,如果项目当前的版本是快照版本,则部署到快照版本仓库地址,否则就部署到发布
版本仓库地址。
快照版本:通常构件需要有自己的版本,版本的值如果是1.0或2.0则是稳定的发布版本,而2.1-SNAPSHOT或2.2-20091214.221414-13是不稳定的快照版本
Maven的快照版本机制就是为了解决上述问题,某人只要将模块A的版本设定为2.1-SNAPSHOT,然后发布到私服中,在发布的过程中,Maven会自动为构件打上时间戳
有了该时间戳,Maven就能够随时找到仓库中该构件2.1-SNAPSHOT版本的最新文件,当另一人需要该构件的时候会自动从仓库中检查模块的2.1SNAPSHOT的最新构件,当
发现有更新时便进行下载,默认,Maven每天检查一次更新(由仓库配置的updatePolicy控制),也可以使用命令行-U参数强制让Maven检查更新,如mvn clean install -U
当项目经过测试后,该快照版本更改为发布版本,将2.1SNAPSHOT更改为2.1,表示该版本已经稳定,只有对应的唯一构件,而2.1-SNAPSHOT往往有很多不同时间戳的构件
快照版本只应该在组织内部的项目或模块间依赖使用,项目不应该依赖于任何组织外部的快照版本依赖,这样会有潜在危险。
从仓库解析依赖的机制:当本地仓库没有依赖构件的时候,Maven会自动从远程仓库下载,当依赖版本为快照版本的时候,Maven会找到最新的快照,这背后的机制是:
1,当依赖范围是system的时候,直接从本地系统解析构件
2,根据依赖坐标计算仓库路径后,尝试直接从本地仓库寻找构件,
3,本地不存在,如果依赖的版本是显示的发布版本构件,则遍历远程仓库,下载
4,如果依赖的版本是RELEASE后者LATEST则基于更新策略取出所有远程仓库的元数据groupId/artifactId/maven-metadata.xml,将其与本地仓库的对应元数据合并后,计算出
RELEASE或者LATEST真实的值,然后基于这个事实的值检查本地和远程仓库
5,如果依赖的版本是SNAPSHOT,则基于更新策略取出远程仓库的元数据groupId/artifactId/version/maven-metadata.xml,将其与本地仓库的对应元数据合并后,得到最新
的快照版本的值,然后基于该值检查本地仓库,或者从远程仓库下载
6,如果最后解析的是时间戳格式的快照,将其时间戳格式的文件至非时间戳格式,如SNAPSHOT,并使用该非时间戳格式的构件,
当依赖的版本不清晰,如RELEASE,LATEST,SNAPSHOT,maven就需要基于更新远程仓库的更新策略来检查更新,首先是<releases><enabled>和<snapshots><enabled>,只有
仓库开启了对于发布版本的支持时,才能够访问该仓库的发布版本构件信息,对于快照版本也是同理,其次是<releases>和<snapshots>的子元素<updatePolicy>,检查更新频率
最后还可以使用命令行加入参数-U,强制检查更新。
当Maven检查完更新策略,并决定检查依赖更新的时候,就需要检查元数据maven-metadata.xml.
之前提到RELEASE和LATEST版本,他们分别对应了仓库中存在的该构件的最新发布版本和最新快照版本,这两个最新是基于groupId/artifactId/maven-metadata.xml计算出来的
<metadata><groupId>,<versioning><latest>,<release>,<version><version>各版本信息
此XML文件列出了仓库中存在的该构件所有可用的版本。lastest指向最新版本,而release指向最新的发布版本,Maven通过合并多个远程仓库及本地仓库的元数据,就能计算出
所有仓库的latest和release分别是什么,但是在依赖声明中使用LATEST和RELEASE是不推荐的做法,因为变更可能会来的很快,而到时发现问题很困难,因此Maven3不再支持
在插件中使用LATEST和RELEASE,如果不设置插件版本其效果和RELEASE一样,Maven会找出最新的发布版构件,还是会存在问题,例如依赖的版本从1.1到1.2可能某个接口
发生了变化,当然会导致Maven构建的失败,当依赖的版本是快照的时候,Maven也需要检查更新,Maven检查仓库元数据groupId/artifactId/version/maven-metadata.xml
<metadata><groupId>,<artifactId>,<version>,<versioning><snapshot><timestamp>,<buildNumber>,其中timestamp和buildNumber两个子元素代表了时间戳和构建号,通过这两
个元素可以获取此快照的最新构件版本实际为什么,通过合并所有远程仓库和本地仓库的元数据,Maven就能知道仓库中该构件的最新快照了
最后,仓库元数据不是永远正确,有时候用户发现无法解析某些构件,或者解析错误的时候,就有可能出现了仓库元数据错误,这时需要手工的或者使用工具Nexus对其修复
镜像:意思是仓库X可以提供仓库Y存储的所有内容,那么X就是Y的一个镜像,也就是任何从Y获得的构件都能够从镜像中获取,例如:http://maven.net.cn/content/groups/public
是中央仓库http://repol.maven.org/maven2在中国的镜像,镜像一般能够提供给比中央仓库更快的服务,可以配置Maven使用镜像来替代中央仓库,编辑settings.xml
<settings><mirrors><mirror><id>maven.net.cn, <name>XXX,<url>http://maven.net.cn/content/groups/public,<mirrorOf>central
其中mirrorOf为central,表示该配置为中央仓库的镜像,任何对中央仓库的请求都会转至镜像,用户可以以同样的方法来配置其他仓库的镜像,另外三个元素id,name,url与
一般仓库无异,表示仓库的唯一标示符,名称,地址,如果镜像需要认证,也可以基于id配置仓库认证。
关于镜像的一个常见的用户是结合私服,由于私服代理任何外部的公共仓库(包括中央仓库),因此对于组织内部的Maven用户来说,使用私服的地址就等于使用所有需要的
外部仓库,这可以将配置集中到私服,从而简化Maven本身的配置,在这种情况下,任何需要的构件都可以从私服获得,私服就是所有仓库的镜像,这时,可以配置这样的一个
镜像:<settings><mirrors><mirror><id>,<name>,<url>http:192.168.1.100/maven2/ ,<mirrorOf>*
该例中mirrorOf的值为星号,表示该配置是所有Maven仓库的镜像,任何对于远程仓库的请求都会被转至http://192.168.1.100/maven2,如果镜像仓库需要认证,则配置一个id
为internal-repository的<server>即可,为了满足一些复杂的需求,Maven还支持高级的镜像配置:
* 匹配所有远程仓库
external:* 匹配所有远程仓库,使用localhost的除外,使用file://协议的除外,也就是匹配所有不在本机上的远程仓库
repo1,repo2,匹配仓库repo1和repo2,使用逗号分隔多个远程仓库
*,!repo1 匹配所有远程仓库,repo1除外,使用感叹号将仓库从匹配中排除
需要注意由于镜像仓库完全屏蔽了被镜像仓库,当镜像仓库不稳定或者停止服务的时候,Maven将无法访问被镜像仓库,因此将无法下载构件
仓库搜索服务:在使用Maven时一个常见的问题是如何寻找需要的依赖,我们不知道其确切的坐标,这时使用仓库搜索服务器来根据关键字得到Maven坐标,以下几个为功能
强大的公共Maven仓库搜索服务:
1 Sonatype Nexus, 下载地址http://repository.sonatype.org/
2 Jarvana 下载地址http://www.jarvana.com/jarvana/
3 MVNbrowser 下载地址http://www.mvnbrowser.com/
4 MVNrepository 下载地址 http://mvnrepository.com/
上述的四个仓库搜索服务都代理了主流的Maven公共仓库,如central,JBoss,Java.net等,预备完备的搜索,浏览,下载等功能。