Maven 主要服务于基于Java平台的项目构建、依赖管理和项目信息管理。
一、安装和配置
maven中央仓库:repo1.maven.org
http://repo1.maven.org/maven2/
1、maven的安装:
略
2、maven的安装目录分析:
maven安装目录下的文件结构:
bin:
包含mvn运行的脚本。脚本文件:mvn与mvnDebug的区别是mvnDebug多了一条MAVEN_DEBUG_OPTS配置,其作用就是运行Maven时开启debug,以便调试Maven本身;
m2.conf是classworlds的配置文件。
boot:
该目录只包含一个文件,以maven 3.0为例,该文件为plexus-classworlds-2.2.3.jar ,是一个类加载器框架,Maven使用该框架加载自己的类库。
conf:
该目录包含的settings.xml。用来在机器上全局地定制Maven的行为。(用户目录/.m2/下的settings用来在用户范围内定制maven的行为)
lib:
该目录包含了所有Maven运行时需要的Java类库
LICENSE.txt:记录了Maven使用的软件许可证
NOTICE.txt:记录了Maven包含的第三方软件
README.txt:包含了Maven的简要介绍,包括安装需求及如何安装的简要指令等。
3、maven配置:
mvn help:system 命令会打印所有的Java系统属性和环境变量
设置HTTP代理:
有些公司处于安全考虑,需要通过安全认证的代理访问互联网,这种情况下,就需要Maven配置HTTP代理,才能让它访问外部仓库。
检查自己的主机是否能访问公共的Maven中央仓库:ping repo1.maven.org
检查代理服务器是否畅通:telnet 服务器地址 端口
编辑settings.xml文件,在<proxies>节点下添加<proxy>元素配置。
注意:proxies下可以有多个proxy元素,当有多个时,第一个被激活的proxy会生效,另外当代理服务需要认证时,就需要配置username和password元素,nonProxyHost元素指定哪些主机名不需要代理(支持通配符)
4、安装m2eclipse:
略
5、Maven安装最佳实践:
(1)、设置MAVEN_OPTS环境变量
设置MAVEN_OPTS 的值为 -Xms128m -Xmx512m
原因是Java默认的最大可用内存往往不能够满足Maven运行的需要,如果没有该配置,则很容易得到java.lang.OutOfMemeoryError。
(2)、配置用户范围settings.xml
Maven用户可以选择配置安装目录下的conf/settings.xml或用户目录/.m2/settings.xml 。前者是全局范围的,整台机器上的所有用户都会受到该配置的影响,而后者是用户范围的,只有当前用户才会受到该配置的影响。
推荐使用用户范围的settings.xml,主要是为了避免无意识地影响到系统中的其他用户。同时也便于Maven升级(因为每次Maven升级,conf/settings.xml文件会被覆盖掉)。
(3)、不要使用IDE内嵌的Maven
无论Eclipse还是NetBeans,当集成Maven时,都会安装上一个内嵌的Maven,这个内嵌的Maven通常会比较新,但带来两个问题:(1)、较新版本的Maven存在很多不稳定因素,容易造成一些难以理解的问题,(2)、除了IDE,也经常使用命令行Maven,如果内嵌版本的Maven与外部安装的Maven版本不一致,容易造成构建行为的不一致。
在Eclipse中,点击Windows->Preferences->Maven->Installation选项,去掉Embedded Maven的勾选,单击Add..按钮,选择Maven安装目录,就可以添加一个外部的Maven.
二、Maven入门
1、POM.xml
Maven项目的核心是pom.xml
POM(Project Object Model, 项目对象模型)定义了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。
在pom.xml中project是pom.xml的根元素;
modelVersion子元素指定了当前POM模型的版本,对于Maven 2及Maven 3 来说,它只能是4.0.0。
在Maven的世界中,任何的jar、pom或者war都是以基于这些基本的坐标进行区分的。
groupId定义了项目属于哪个组,这个组往往和项目所在的组织或公司存在关联。譬如com.goolecode.myapp。
artifactId定义了当前Maven项目在组中唯一的ID,一般为不同的子项目(模块)分配artifactId,如myapp-util、myapp-domain、myapp-web等。
version指定了项目当前的版本。 例如1.0-SNAPSHOT。SNAPSHOT意为快照,说明该项目还处于开发中,是不稳定的版本。或者是:1.1 、2.0等
name:声明了一个对于用户更为友好的项目名称,(不是必须的,但推荐为每个POM声明name,以方便信息交流)。
2、项目主代码
项目主代码和测试代码不同,项目的主代码会被打包到最终的构件中(如jar),而测试代码只在运行测试时用到,不会被打包。
遵循Maven的约定,maven项目的主代码位于src/main/java目录。
注:当主代码位于src/main/java(即遵循Maven的约定)时,无须额外配置,Maven会自动搜寻该目录找到项目主代码。
3、项目测试代码
项目测试代码与项目主代码应该分别位于独立的目录中。Maven项目中默认的测试代码目录是src/test/java。另外,Java中JUnit是事实上的单元测试标准。如果项目中要使用JUnit,需要在pom.xml中添加<dependency>节点,如下所示:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
Maven在编译时会首先去本地仓库中查找junit-4.7.jar,如果未找到,就会自动访问中央仓库(http://repo1.maven.org/maven2/),下载需要的文件到本地仓库。
注意:scope元素为依赖范围,若依赖范围为test,则表示该依赖只对测试有效。默认值为compile,表示该依赖对主代码和测试代码都有效。
由于历史原因,Maven的核心插件之一——compiler插件默认只支持编译Java 1.3 ,因此如果需要该插件支持Java 5 ,则需要在pom.xml中<build>节点下的<plugins>节点下添加对应的<plugin>节点,如:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
4、生成可执行的jar
默认打包生成的jar是不能够直接运行的,因为带有main方法的类信息不会添加到manifest中。为了生成可执行的jar文件,需要借助maven-shade-plugin,配置该插件如下:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.juvenxu.mvnbook.helloworld.HelloWorld</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
配置完成后,执行package命令,会在target/目录下找到两个jar,其中一个以original开头,表示该jar是原始的jar,不可直接执行,另一个就是可执行的jar。
5、mvn 命令
clean命令:清理输出目录target/
compile命令:编译项目主代码,默认情况下,Maven构建的所有输出都在target/目录下。
test命令:执行测试代码
package命令:打包命令,默认输出目录为:target/
install命令:安装命令,即将打包后的jar、pom安装到Maven本地仓库中,供其他项目使用
注意:执行test之前会先执行compile命令,执行package之前会先执行test命令,执行install之前会执行package命令。
6、使用Archetype生成项目框架
Maven提供了Archetype可以帮助我们快速勾勒出项目框架。使用方法:
如果是Maven 3 ,简单地运行 mvn archetype:generate
如果是Maven 2, 最好运行如下命令:mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-5:generate
此外,也可以开发自己的Archetype,然后在这些项目中使用自定义的Archetype来快速生成项目骨架。
7、m2eclipse简单使用
在m2eclipse中执行Maven构建时,默认的选项中可能没有我们想要执行的Maven命令,比如默认带有mvn test,但我们想执行mvn clean test,我们可以在Maven build以自定义Maven运行命令,在弹出对话框的Goals一项中输入我们想要执行的命令,如clean test,设置一下Name,单击Run即可,并且,下次选择Maven build,或者使用快捷键“Alt + Shift + X, M”快速执行maven构建时,上次的配置直接就能在历史记录中找到。
三、坐标与依赖
1、Maven坐标详解
Maven定义了一组规则:世界上任何一个构件都可以使用Maven坐标唯一标识。
Maven坐标的元素包括:groupId、artifactId、version、packaging、classifier。
groupId:定义当前Maven项目隶属的实际项目。
比如:SpringFramework这一实际项目,其对应的Maven项目会有很多,如spring-core、spring-context等。
artifactId:定义实际项目中的一个Maven项目(模块),推荐的做法是使用实际项目名称作为artifactId的前缀。
比如:artifactId是nexus-indexer,就是使用了实际项目名nexus作为前缀的。
version:定义Maven项目当前所处的版本
packaging:定义Maven项目的打包方式,默认的打包方式为jar。
classifier:用来帮助定义构建输出的一些附属构件。
附属构件与主构件对应,有些项目不仅会输出主构件,例如nexus-indexer-2.0.0.jar,也可能通过一些插件生成nexus-indexer-2.0.0-javadoc.jar、nexus-indexer-2.0.0-sources.jar。这里的javadoc和sources就是两个附属构件的classifier。这样附属构件也就拥有了自己的唯一的坐标。
注意:不能直接定义项目的classifier,因为附属构件不是项目直接默认生成的,而是由附加的插件帮助生成的。
另外,项目构件的文件名是与坐标相对应的。一般的规则为:artifactId-version [-classifier] .packaging
2、依赖的配置
根元素project下的dependencies可以包含一个或者多个dependency元素,以声明一个或者多个项目依赖:
groupId、artifactId、version:依赖的基本坐标
type:依赖的类型,对应于项目坐标定义的packaging,默认值为jar
scope:依赖的范围
optional:标记依赖是否可选
exclusions:用来排除传递依赖
(1)、依赖范围
依赖范围用来控制依赖与三种classpath(编译classpath、测试classpath、运行classpath)的关系。
Maven有以下几种依赖范围:
compile:编译依赖范围。如果没有指定,默认使用该依赖范围,使用此依赖范围的Maven依赖,对于编译、测试、运行三种classpath都有效。
test:测试依赖范围。使用此依赖范围的maven依赖,只对于测试classpath有效,在编译主代码或者运行项目的使用时将无法使用此类依赖。
provided:已提供依赖范围,使用此依赖范围的maven依赖,对于编译和测试classpath有效,但在运行时无效。
runtime:运行时依赖范围。使用此依赖范围的maven依赖,对于测试和运行classpath有效,但在编译主代码是无效。
system:系统依赖范围。该依赖与三种classpath的关系,和provided依赖范围完全一致。但是,使用system范围的依赖时必须通过systemPath元素显式地指定依赖文件的路径。(此类依赖不是通过Maven仓库解析的,往往与本机系统绑定,可能造成构件的不可移植,因此应该谨慎使用)
import(Maven 2.0.9及以上):导入依赖范围
(2)、传递性依赖
构件A依赖于构件B, 构件B依赖于构件C, 那么构件A与构件C之间就存在传递性依赖。我们可以说:A对于B是第一直接依赖。 B对于C是第二直接依赖。A对于C是传递性依赖。
Maven会解析各个直接依赖的POM,将那些必要的间接依赖以传递性依赖的形式引入到当前的项目中。
依赖范围对传递性依赖的影响:(下图:最左边一列是第一直接依赖范围, 最上面一行是第二直接依赖范围, 中间交叉单元是传递性依赖范围)
(3)、依赖调解
当传递性依赖造成问题时,我们需要清楚该怎样引入传递性依赖(采用哪条路径引入)。这就是依赖调解。
例如:项目A有这样的依赖关系:A->B->C->X(1.0)、A->D->X(2.0),X是A的传递性依赖,但是两条依赖路径上有两个版本的X,那么哪个X会被Maven解析使用呢?这时就需要依赖调解原则。
依赖调解原则:
第一原则:路径最近者优先。即路径短的优先,如上例中X(1.0)的路径长度为3,而X(2.0)的路径长度为2,因此X(2.0)会被解析使用。
第二原则:第一声明者优先。在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定谁被解析,顺序靠前的版本优先。
(4)、可选依赖
如果项目A依赖于项目B,项目B实现了两个特性,其中的特性一依赖于X,特性二依赖于Y,而且这两个特性是互斥的,用户不可能同时使用两个特性。那么就会存在可选依赖:A->B、B->X(可选)、B->Y(可选),这里X、Y是可选依赖,依赖将不会传递。
可选依赖,在dependency节点中的<optional>元素表示这两个依赖时可选依赖:具体形式为:<optional>true</optional>
在理想情况下,不应该使用可选依赖。可以将两个可选的依赖,实现为基于同样groupId,分配不同的artifactId的模块。
(5)、关于依赖的最佳实践
【1】、排除依赖
比如当需要发布一个项目的稳定版本时,发现其存在SNAPSHOT版本的某个传递性依赖。而SNAPSHOT版本不稳定可能影响当前的项目。因此,可以使用排除依赖,来排除掉该SNAPSHOT版本,并使用另一个稳定版本来代替。
具体做法是:在dependency节点下,<exclusions>子节点下添加<exclusion>元素。例如:
<dependency>
...
<exclusions>
<exclusion>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactedId>projectt-c</artifactedId>
</exclusion>
</exclusions>
</dependency>
注意:声明exclusion的时候只需要groupId和artifactId,而不需要version元素。因为Maven解析后的依赖中,不可能出现groupId和artifactId相同,但是version不同的两个依赖。
【2】、归类依赖
可能存在这种情况,pom.xml中声明了多个依赖,但是都许多依赖时来自同一个项目的不同模块。因此要求这些依赖的版本都是相同的。当需要将该依赖项目升级到高版本时,就需要所有该项目的模块依赖都要升级。为了方便,可以使用归类依赖。
具体做法:使用Maven属性
例如:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook.account</groupId>
<artifactedId>account-email</artifactedId>
<name>Account Email</name>
<version>1.0.0-SNAPSHOT</version>
<properties>
<springframework.version>2.5.6</springframework.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactedId>spring-core</artifactedId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactedId>spring-beans</artifactedId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactedId>spring-context</artifactedId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactedId>spring-context-support</artifactedId>
<version>${springframework.version}</version>
</dependency>
</dependencies>
</project>
Maven运行时会将POM中所有的${springframework.version}替换成实际值2.5.6。
【3】、优化依赖
通过mvn命令,可以查看已解析依赖(Resolved Dependency),可以直观地反映项目的依赖情况,使我们可以更好的优化依赖关系。
mvn dependency:list : 查看项目的所有顶层依赖
mvn dependency:tree : 查看项目的依赖树(包括顶层依赖、二层、三层依赖等)
mvn dependency:analyze : 分析当前的项目依赖。
注意:mvn dependency:analyze 命令的结果有两个部分:第一部分:Used undeclared dependencies,指项目中使用到的,但是没有显式声明的依赖。这类依赖意味着潜在的风险,建议显式声明任何项目中直接用到的依赖。 第二部分:Unused declared dependencies,指项目中未使用的,但是显式声明的依赖,对于 这样的依赖,我们不应该简单地直接删除其声明,而应该仔细分析。因为dependency:analyze只会分析编译主代码和测试代码需要用到的依赖,一些执行测试和运行时需要的依赖它就发现不了。
四、仓库
Maven可以在某个位置统一部署所有Maven项目共享的构件,这个统一的位置就是仓库。
1、仓库的布局
Maven仓库是基于简单文件系统存储的,Maven会根据任何一个构件的唯一坐标,定位到其在仓库中的唯一存储路径。
其定位过程是:假设一个构件:groupId = org.testng、artifactId = testng、version=5.8、classifier=jdk15、packaging=jar
** 基于构件的groupId准备路径: 将org.testng 转换成org/testng/ (即将句点分隔符替换成路径分隔符,最后再加一个路径分隔符)
** 基于构件的artifactId准备路径:结果为:org/testng/testng/ (在上一步基础上,加上artifactId,再加路径分隔符)
** 使用版本信息: 结果:org/testng/testng/5.8/
** 依次加上artifactId,构件分隔符连字符,以及version,结果为:org/testng/testng/5.8/testng-5.8
** 如果构件有classifier,就加上构件分隔符和classifier,结果为:org/testng/testng/5.8/testng-5.8-jdk5
** 检查构件的extension,若extension存在,则加上句点分隔符和extension。extension是由项目的packaging决定的:结果:org/testng/testng/5.8/testng-5.8-jdk5.jar
这个结果就是构件在仓库中的实际存储路径。
2、仓库的分类
maven仓库有两类:本地仓库和远程仓库
远程仓库又有如下的种类:中央仓库、私服、其他公开的远程仓库。
本地仓库:
Maven项目所在本机上的仓库。当Maven在执行编译或测试时,如果需要使用依赖文件,它总是基于坐标先使用本地仓库的依赖文件。
默认的本地仓库目录为:用户/.m2/repository/
通过配置settings.xml中的loaclRepository元素的值,可以设置本地仓库的目录。
中央仓库:
是一个默认的远程仓库,Maven的安装文件自带了中央仓库的配置。可以使用解压工具打开jar文件:Maven安装目录/lib/maven-model-builfer-3.x.x.jar(在Maven 2中, 对应 maven-2.2.1-uber.jar),然后访问路径org/apache/maven/model/pom-4.0.0.xml,可以看到该xml文件中配置了中央仓库的信息,如下:
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
注:该pom-4.0.0.xml是所有Maven项目都会继承的超级POM
私服 :
架设在局域网内的仓库服务,用来代理广域网上的远程仓库,供局域网内的Maven用户使用。局域网仓库,具有节约外网带宽、加速Maven构建、提高稳定性、增强控制、降低中央仓库负荷等优点。
3、远程仓库的配置
如果默认的中央仓库没有需要的项目,可能项目需要的构件在另一个远程仓库,这时,就需要在项目POM中配置该仓库,如下:
在repositories元素下,可以使用repository子元素声明一个或者多个远程仓库。注意Maven自带的中央仓库使用的id为central,如果其他的仓库声明也使用该id,就会覆盖中央仓库的位置。
<project>
...
<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>
</snapshots>
<layout>default</layout>
</repository>
</repositories>
...
</project>
其中,releases元素控制Maven对于发布版构件的下载,例如releases元素的enabled值为ture,表示开启JBoss仓库的发布版本下载支持;
snapshots元素控制Maven对于快照版本构件的下载,例如snapshots元素的enabled值为false,表示关闭JBoss仓库的快照版本下载支持;
对于releases和snapshots来说,除了enabled,它们还包含另外两个子元素updatePolicy和checksumPolicy:
元素updatePolicy用来配置Maven从远程仓库检查更新的频率,默认的值是daily。其他值为:never、always、interval
元素checksumPolicy用来配置maven检查检验和文件的策略。默认值为warn,其他值为:fail 、ignore
(1)、远程仓库的认证
大部分远程仓库无须认证就可以访问,但有时出于安全考虑,需要提供认证信息才能访问一些远程仓库。为了能够访问需要认证信息的远程仓库,需要在settings.xml文件中配置认证信息。(为什么不能配置在POM中,而要配置在settings中?因为POM文件最终会被提交到代码仓库中,供所有人访问,settings一般只放在本机,更加安全)。
通过settings.xml中servers元素及其server子元素配置仓库认证信息,server子元素id标识需要认证的仓库,username、password标识用户名、密码。
(2)、部署至远程仓库
Maven可以将构件部署到远程仓库中,具体做法是:编辑项目pom.xml文件。配置distributionManagement元素,配置正确后执行 mvn clean deploy命令。
distributionmanagement包含repository和snapshotRepository子元素,前者表示发布版本构件的仓库,后者表示快照版本的仓库。
4、快照版本
对于开发中的项目,版本发布频繁,为了简化发布、提高开发效率、减少版本号滥用等原因,Maven引入了快照版本机制。快照版本的构件在发布的过程中,maven会自动为构件打上时间戳,根据时间戳,Maven就能够随时找到仓库中该构件的最新版本文件,当用户需要该快照版本构件时,Maven会自动从仓库中检查最新版本的构件,当发现有更新时就进行下载。
基于快照版本机制,发布者在构建成功后发布到仓库中,使用者可以完全不用考虑构件的构建过程,并且能够确保随时得到的是最新的快照构件。
注:当项目完善后需要发布的时候,就应该将快照版本更改为发布版本。另外快照版本只应该在组织内部的项目或模块间依赖使用。
5、从仓库解析依赖的机制
maven是根据怎样的规则从仓库解析并使用依赖构件的呢?
maven的依赖解析机制可以概括如下:
(1)、当依赖的范围是system的时候,Maven直接从本地文件系统解析构件;
(2)、根据依赖坐标计算仓库路径后,尝试直接从本地仓库寻找构件,如果发现相应构件,则解析成功;
(3)、在本地仓库不存在相应构件的情况下,如果依赖的版本是显式的发布版本构件,如1.2, 2.1-beta-1等,则遍历所有的远程仓库,发现后,下载并解析使用;
(4)、如果依赖的版本是RELEASE(最新发布版本)或者LATEST(最新版本包括快照版本)(此时依赖的版本不清晰),则maven会基于更新策略读取所有远程仓库的元数据groupId/artigactId/maven-metadata.xml,将其与本地仓库的对应元数据合并后,计算出RELEASE或LATEST真实的值,然后基于这个真实的值检查本地和远程仓库;
(5)、如果依赖的版本是SNAPSHOT,则基于更新策略读取所有远程仓库的元数据groupId/artigactId/version/maven-metadata.xml,将其与本地仓库的对应元数据合并后,得到最新快照版本的值,然后基于该值检查本地仓库,或者从远程仓库下载。
(6)、如果最后解析的构件版本是时间戳格式的快照,如1.4.1-20091104.121450-121,则复制其时间戳格式的文件至非时间戳格式,如SNAPSHOT,并使用该非时间戳格式的构件。
下面描述一下,maven是如何根据maven-metadata.xml计算出RELEASE、LATEST、SNAPSHOT的值的:
仓库中基于groupId和artifactId的maven-metadata.xml的内容示例如下:
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus</artifactId>
<versioning>
<latest>1.4.2-SNAPSHOT</latest>
<release>1.4.0</release>
<versions>
<version>1.3.5</version>
<version>1.3.6</version>
<version>1.4.0-SNAPSHOT</version>
<version>1.4.0</version>
<version>1.4.0.1-SNAPSHOT</version>
<version>1.4.1-SNAPSHOT</version>
<version>1.4.2-SNAPSHOT</version>
</versions>
<lastUpdated>20091214221557</lastUpdated>
</versioning>
</metadata>
该文件列出了仓库中存在的该构件所有可用的版本,同时latest元素指向了这些版本中最新的那个版本。release元素指向这些版本中最新的发布版本。通过合并所有远程仓库和本地仓库的元数据,Maven就能知道所有仓库中该构件的最新、最全的版本信息。
6、镜像
如果仓库X可以提供仓库Y存储的所有内容,那么就可以认为X是Y的一个镜像。
例如:http://maven.net.cn/content/groups/public是中央仓库http://repo1.maven.org/maven2在中国的镜像。可以配置Maven使用该镜像来替代中央仓库,编辑settings.xml
<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>
上例中,<mirrorOf>的值为central,表示该配置为中央仓库的镜像,任何对于中央仓库的请求都会转至该镜像,用户也可以使用同样的方法配置其他仓库的镜像。
关于镜像的一个更为常见的用法是结合私服。可以配置任何需要的构件都可以从私服获得,私服就是所有仓库的镜像。配置使用私服作为镜像的配置示例如下:
<settings>
...
<mirrors>
<mirror>
<id>interal-repository</id>
<name>Internal Repository Manager</name>
<url>http://192.168.1.100/maven2/</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
...
</settings>
该例中<mirrorOf>的值为星号,表示该配置时所有Maven仓库的镜像,任何对于远程仓库的请求都会被转至http://192.168.1.100/maven2/。如果需要认证,配置一个id为internal-repository的<server>即可。
Maven还支持更高级的镜像配置:
【】<mirrorOf>*</mirrorOf> : 匹配所有的远程仓库
【】<mirrorOf>external:*</mirrorOf> : 匹配所有远程仓库,使用localhost的除外,使用file:// 协议的除外。(即匹配所有不在本机上的远程仓库)
【】<mirrorOf>repo1,repo2</mirrorOf>:匹配仓库repo1和repo2,使用逗号分隔多个远程仓库
【】<mirrorOf>*, !repo1</mirrorOf>:匹配所有远程仓库,repo1除外,使用感叹号将仓库从匹配中排除。
7、仓库搜索服务
几个常用的、功能强大的公共Maven仓库搜索服务
(1)、Sonatype Nexus
地址:http://repository.sonatype.org/
Nexus提供关键字搜索、类名搜索、坐标搜索、检验和搜索等功能。
(2)、Jarvana
地址:http://www.jarvana.com/jarvana/
Jarvana提供了基于关键字、类名的搜索。(貌似不能访问,打开地址提示该域名正在出售!)
(3)MVNbrowser
MVNbrowser只提供关键字搜索的功能。
(4)MVNrepository
MVNrepository的界面比较清新,提供了基于关键字的搜索、依赖声明代码片段、构件下载、依赖与被依赖关系信息、构件所包含信息等功能。