现在,运行jar目标并且看看Maven的输出吧;它将包含下面如下这些。
Attempting to download spring-core-1.1.4.jar.266K downloadedAttempting to download spring-web-1.1.4.jar.111K downloaded
图1-1显示了jar目标触发的一系列事件:
1.Maven查看POM,依据project.xml的定义,看到在springframework组中的两个人造物的依赖关系。它将载你本地Maven的资源库中检查spring-core-1.1.4.jar和spring-web-1.1.4.jar。
2.当Maven找不到这些文件,它将到http://www.ibiblio.org/maven/springframework/jars/寻找JAR文件。这些JAR文件会被下载并放置于你本地Maven的资源库中。它们也被添加到你项目的classpath中。下次在你的项目查询这些文件时,Maven将在你本地的资源库中提供它们。
图1-1.Maven本地和远程资源库为test application项目提供的spring Jar 刚刚发生了什么?
Maven为你节省了相当的时间和不必要的麻烦。Maven到来之前,依赖关系常常被捆绑到一个项目的目录或者项目应该指向到添加正确的JAR到你的classpath。使用Maven管理依赖关系显然有着明显的优势;作为初学者,如果你的项目依赖30个外部的JAR文件,这就不需要在你的资源库中存储成兆的JAR文件。这意味着当你在项目的外部检查资源控制的时候更少的存储空间和更快的下载时间。另外,如果你有多个项目依赖相同的外部依赖,Maven仅需要下载一次依赖关系,并且每个项目引用一个单独的副本在你本地的资源库中。当依赖关系能够从Maven资源库远程下载的时候,没有强制的原因让你存储你项目的依赖关系的版本。
当Maven下载依赖关系,其在你本地的机器上从远程的Maven资源库拷贝一个文件到你本地的Maven资源库。Maven如何定位依赖关系的?它使用project.xml中dependency元素的信息,如图1-2所示。
图1-2.POM和Maven资源库的映射 指定的groupId告诉Maven查看特定的目录-springframework。指定type告诉Maven查找特定的子目录如jar和war(注意s是Maven附加到type元素上的);本例中,type是被忽略的,JAR类型是默认类型。当你指定了artifactId,你正告诉Maven哪个文件将从jar目录下载。顶级目录表现为组标示符,JAR文件名的第一部分表现为artifact标示符,文件名最后的部分,包括扩展名表现为version标示符。Maven使用下面的公式来决定一个来自于资源库中的依赖关系。[REPO_ROOT]参考你远程的资源库:
[REPO_ROOT]/<groupId>/<type>s/<artifactId>-<currentVersion>.<type>
提示
Maven2.0的说明中,资源库可能开始于类似Java包的结构。作为springframework的替代,groupId被提议的结构为org.springframework.另外,每个版本将有一个分隔目录用以增加Maven资源库的效率。更多有关改变的提交建议,参见http://docs.codehaus.org/display/ MAVEN/Repository+Layout+-+Final.
一个本地的资源库来处理依赖关系。在Unix机器上,你的Maven资源库能在~/.maven/repository目录找到,在Windows机器上,你的Maven的资源库在你的%USERPROFILE%目录。如果你看一看本地Maven的资源库,你将会注意到它正包含一个springframework的目录。%USERPROFILE%\.maven\repository\springframework\jars目录包含spring-core依赖关系的两个:spring-core-1.1.4.jar文件和spring-core-1.1.4.jar.md5文件,其包含MD5文件用于验证sprint-core JAR文件的完整性。Maven 1当前并没有使用MD5来验证完成品的完整性,但在将来的版本可能会用其来验证完成品的完整性。
提示
在Windows机器上,%USERPROFILE%通常决定于C:\D-ocuments and Settings\vmassol这种目录。%USERPR-OFILE%被用在Unix的主目录。(%USERPROFILE% isused in the spirit of the abbreviation for a Unix home directory.)
关于......使用id元素?
如果你工作在现存的Maven项目,你可能有依赖关系使用id元素。下面的dependencies元素示范了使用单独id元素来附加Jakarta Commons Math的1.0版本:<;dependencies><;dependency><;id>commons-math<;/id><;version>1.0<;/version><;/dependency><;/dependencies>单独使用id元素工作仅在groupId和artifactId匹配时,如果你浏览Maven资源库,你将看到下面的目录结构:
/commons-math
/jars
commons-math-1.0.jar
commons-math-1.1.jar
使用id元素工作,单独的id标记已经不被赞成使用并在Maven 2中消失。当你看到别的Maven项目中使用dependencies的速记符号时,请尝试使用groupId和artifactId来标识你的依赖关系。
依赖快照 如果你开发的程序依赖的依赖关系经常改变,你可能想将依赖的每个依赖关系替代为最近构件的硬编码的版本。在一个项目依赖的依赖关系还处在beta的版本,或你正开发一系列项目依赖的Maven项目时时特别有用,这将在第3章论述。本实验,你将学习到如何依靠快照。
我该如何做?
在你的依赖关系块儿中指定一个明确的版本,使用SNAPSHOT关键字作为版本名称的一部分。每次你执行Maven目标时,Maven将从远程资源库中检查较新的依赖关系。如果远程资源库的版本较新Maven将下载其到本地资源库。例如:下面的依赖关系将一直下载spring的新版JAR文件。
<dependency>
<groupId>springframework
</groupId>
<artifactId>spring
</artifactId>
<version>1.2-SNAPSHOT
</version>
</dependency>
刚刚发生了什么?
当你使用SNAPSHOT依赖关系,你正告诉Maven使用远程资源库的最新版本。在你使用多项目插件或者当你依赖的一个完成品尚处于开发阶段这将得心应手。在你工作的团队仅有较少的开发者组成时,最好也常这么做。你将使用SNAPSHOT依赖关系当你的项目依赖一个最近的开发或者非正式版本的特别组件。SNAPSHOT依赖关系应该在开发阶段被保留,并且,概括说,你不用改发布一个依赖于SNAPSHOT依赖关系的项目。
执行脱机构建 如果你需要在一个离线的情况下使用Maven,你可能需要知道如何确使Maven不检查最新的SNAPSHOT依赖关系。本实验将向你展示如何用Maven执行脱机构建。
我该如何做?
这个方法很简单:仅仅使用-o命令行选项。例如,如果你没有网络连接,但又想执行测试目标,运行Maven -o test。Maven将执行这个test目标而不检查依赖关系。如果你的项目没有依赖SNAPSHOT构建,你也可以断看你的环境来添加-o标志。如果你依赖SNAPSHOT构建,你将需要使用-o标志,Maven将在每次执行目标时尝试检查最新的SNAPSHOT。在这种情况下不使用-o标志本项目将不会构建成功。
关于...... 执行离线构建如果你不想下载任何完成品?
当然,这将不会工作。离线构建的工作,你必须已经有必需的依赖关系在你本地的资源库。项目最简单的获得Maven下载依赖
关系的方法是在每个Maven项目实例简单的运行“noop”目标,build:start。这个目标执行之前任何其它的目标并不执行任何动作。如果你运行build:start,Maven将从project.xml获得获取任何依赖关系。
使用Maven控制台 如果你再三的从命令行运行Maven,你可以通过Maven控制台来节省时间。Maven控制台提供一个“外壳”,在这你可以键入目标的名称来执行Maven。通过使用Maven可以避免每次载你想运行一个Maven目标时Java Virtual Machine(JVM)启动的等待。
我该如何做?
Maven Console是一个插件,你可以通过键入maven console在命令提示符。这将产生下面的输出:
__ __
| \/ |__ _Apache__ ___
| |\/| / _` \ V / -_) ' \ ~ intelligent projects ~
|_| |_\__,_|\_/\___|_||_| v. 1.0.2The following commands are available:list - list all available goalshelp - this message<goalname> - attain a goalquit - quits the consoletest-application 1.0 >
目前,你可以在命令行执行任何你能执行的目标。开始是一下;键入 java:compile。Maven将执行 java:compile目标并返回提示符其它的目标。在一个序列中运行两个目标,你可以在提示符处输入它们,通过“空格”-例如, clean test。众所周知作为“goal chaining”这是你想通过Maven获得指定一系列目标的方法。退出Maven Console,键入quit,查看有效目标列表,键入list。
刚刚发生了什么?
在Maven Console下Maven执行java:compile目标非常之快,不信么?当你使用Maven Console时你所执行的目标是在一个现成的JVM下。当你从命令行运行Maven时,你每次运行一个目标都不得不等待JVM的启动。如果你不确信其对性能的提升,自己试试看。在命令行下运行java:complie 10次,再在Maven Console下同样运行java:compile 10次。注意时间的差别,你将发现JVM启动的时间开始增加。如果你找到你自己常用的Maven目标,Maven Console将通过启动JVM一次为来节省时间。
生成Eclipse项目 我打赌你一定想在IDE下工作。Maven通过插件来与Eclipse,InelliJ,IDEA,JBuilder,JDeveloper以及Emacs集成。Maven很好的与全部这些工作集成,本实验关注