开头说
Maven项目使用或生成的artifact都存放在Maven仓库中。本讲介绍Maven仓库和使用,如何使用Nexus管理仓库、路由设置、资源查找、定时任务,仓库元数据模型等。
Maven仓库
仓库分为本地的仓库和远程的仓库。当我们使用mvn install命令时,会把jar包安装到本地仓库中。我们构建项目的时候,会先从本地仓库查找对应的jar包,找不到就会去远程仓库下载。
更新策略
是不是说只要本地仓库有了对应的jar包,就不会去远程仓库下载了呢?并不是这样的。
远程仓库还可分为3种,release、 snapshot、plugin。release仓库存放固定版本的artifact,这种多次下载都是相同的artifact,如:
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
</dependency>
snapshot仓库存放版本号是SNAPSHOT结尾的artifact。这个隔几天下载,里面的内容有可能发生改变:
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-kernel</artifactId>
<version>1.7.0-SNAPSHOT</version>
</dependency>
plugin仓库是专门存放插件的仓库,插件可能是release版本的,也可能是snapshot版本的。
在超级POM文件定义了仓库的种类及属性。repository的snapshot/enabled表示当前是否是snapshot的仓库,false表示release的仓库。从下面的配置,我们注意到插件仓库的updatePolicy配置了更新策略。对于release的仓库,可选always, daily,
interval:X或never。always表示每次触发构建时都去远程仓库下载,daily表示每天的,interval:X表示经过X分钟才会去远程下载。never表示本地有了就再也不会去远程的下载了。但是对于snapshot的仓库只能选择always、daily、interval:X。这个标签的默认值是daily。
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
</pluginRepository>
</pluginRepositories>
多个仓库
根据第一讲,我们知道有项目的pom文件,父pom和超级pom。 那如果每个pom文件都定义了仓库,而且仓库不同怎么办?这时,Maven会先在项目pom定义的第一个仓库寻找,寻找不到就去第二个仓库找。最终还找不到就去父pom文件定义的仓库去找,最后去超级pom定义的仓库找。原书的图:
但是如果我们在setting.xml文件定义了仓库,这个仓库的优先级高于所有pom文件定义的仓库。仓库的具体顺序可以通过mvn help:effective 命令查看。
仓库管理者
大型的开发团队,有很多开发人员,如果大家都在build项目会造成网络的拥堵,尤其是项目中有很多snapshot的依赖时。这时,仓库管理者就作为远程仓库的代理,同一个artifact被下载时,就会缓存在管理者的仓库中,之后再有下载请求就直接从管理者获取。另外还可以施加一些权限控制。
仓库管理者的第二个作用是作为公共仓库。这个公共仓库,仅是对于公司内部而言,所以不必对外暴露不稳定的版本,具有安全性。对于多依赖的各子项目,直接从代码构建很耗时,如果从公司的仓库下载就方便很多。
一些开源的仓库管理者都很不错,如Nexus、Archiva、Artifactory。他们的比较可以参考这里。
Nexus
Nexus有开源版本和专业版本,其中开源版本的功能有:
- 主持和维护仓库
- 代理远程仓库的请求
- 仓库分组,每组仓库分配一个特殊的url
- 作为项目站点的主机
- 权限控制
- artifact的搜索功能
- 仓库管理的定时任务
- 对外的RESTful服务
- 开箱即用,但也可以通过插件添加更多功能
安装和使用
在这个网站可以下载http://www.sonatype.org/nexus/go安装包。
之后可以通过执行nexus.exe /run运行Nexus,在浏览器访问http://localhost:8081/可以看到如下的界面:
创建宿主仓库
创建代理仓库
创建组合仓库
这样,我们就可以在Maven的settings.xml文件的仓库中配置上面的仓库地址。这样maven在寻找插件,就会先从Nexus的组合仓库寻找。
路由规则
这里我们配置阻隔^/org/apache/axis2/.*的jar,这样在构建项目时,不会下载对应的jar包了。
定时任务
资源查找
插件查看
元数据模型
这个maven-metadata.xml的龙骨如下:
<metadata modelVersion=.. >
<groupId/>
<artifactId/>
<version/>
<versioning>
<latest/>
<release/>
<snapshot>
<timestamp/>
<buildNumber/>
<localCopy/>
</snapshot>
<versions/>
<lastUpdated/>
<snapshotVersions>
<snapshotVersion>
<classifier/>
<extension/>
<value/>
<updated/>
</snapshotVersion>
</snapshotVersions>
</versioning>
<plugins>
<plugin>
<name/>
<prefix/>
<artifactId/>
</plugin>
</plugins>
</metadata>
那么这个文件有什么用呢?前面讲到的更新策略小节,maven会检查这个文件记录的snapshot/timestamp标签(即上次更新时间),来确定此次是否更新。
<snapshot>
<timestamp>20140921.110455</timestamp>
<buildNumber>1943</buildNumber>
</snapshot>
当我们下载snapshot版本的依赖时,总会下载这个maven-metadata.xml并放到本地对应的目录下面,更改名称以区分来源的远程仓库(我配置的仓库id是alimaven)。
另外,当我们在引入的插件配置中没有指定版本时,下载时也会下载这个maven-metadata.xml,但是只有最新版本的jar才会被下载。
<latest>1.6.2</latest>
<release>1.6.2</release>
<versions>
<version>1.0</version>
<version>1.1</version>
<version>1.2</version>
<version>1.3</version>
<version>1.4</version>
<version>1.4.1</version>
<version>1.5</version>
<version>1.5.1</version>
<version>1.5.2</version>
<version>1.5.3</version>
<version>1.5.4</version>
<version>1.5.5</version>
<version>1.5.6</version>
<version>1.6.0</version>
<version>1.6.1</version>
<version>1.6.2</version>
</versions>
还有一种类型是,当我们通过install,maven会在目录下生成一个maven-metadata-local.xml文件,当我们把它部署到远程仓库时,这个文件也会被提交。
总结
本讲我们介绍了Maven仓库的种类,围绕仓库介绍了仓库的更新策略,仓库的生效顺序,仓库的元数据信息。对于仓库的管理,我们简单介绍了Nexus各项功能。