项目开发过程中组员对于Maven的使用仍然存在很多的问题和疑问,下面将根据一个实际例子对Maven如何管理项目做一个阐述。
1. 项目目标
由于本节是本系列的第一小节,我希望从基础开始描述,主要从一个Console Application开始由浅入深描述概念、步骤及其他工具使用中所需注意步骤。
2. 准备工作
2.1 下载文件
Maven的工具下载地址请去:http://maven.apache.org/download.cgi,直接下载bin.zip版本即可。
下载来的文件解压后放置于某目录(今后以$maven环境变量代替)。
2.2 配置环境变量
MAVEN_HOME | 你自己的Maven解压路径 |
MAVEN | %MAVEN_HOME%\bin |
(可选)MAVEN_OPTS | -Xms256m -Xmx512m |
PATH | 添加%MAVEN% |
2.3 验证
打开控制台,输入mvn -version验证maven是否正确安装。
3. 实战
3.1 新建项目
到你自己的工作目录,控制台中运行如下目标(goal)创建项目:
mvn archetype:create -DgroupId=com.freesoft.mvnConsoleApp -DartifactId=mvn-console-app
注意第一次运行的时候maven会自动去服务器下载最新的一些工具包组件(maven中称为artifacts,神器??)到你本地的repository中。
运行结果如下:
3.2 项目结构分析
项目创建完成了,我们能够得到如下所示的目录结构:
我们能够知道的是:
- 项目的/src/main/java目录下保存了项目的源文件;
- 项目的/src/test/java目录下保存了该项目的测试文件;
- 项目根目录下保存了一份POM.xml文件,我们称之为Project-Object-Model,即项目-对象模型文件,这份文件及其重要,是Maven的核心配置文件。该文件结构内容比较复杂,所以我们放到后面进行讲解。
3.3 编译
我们在项目根目录下输入以下命令进行编译:
mvn package
经过一系列步骤之后,maven在项目根目录下建立了target目录,并生成了一个jar包,我们可以测试包的运行效果:
java -cp mvn-console-app-1.0-SNAPSHOT.jar com.freesoft.mvnConsoleApp.App
至此,整个简单的控制台项目已经能够正常运行,我们下面开始讲解每个步骤的理论知识。
3.4 回顾
3.4.1 关于新建项目
关于“3.1 新建项目”中我们通过mvn archetype:create的命令我们当时称之为一个goal,实际是因为archetype是maven的一个内置插件(plugin),这个插件包含了一个create目标(当然create命令支持-DgroupId -DartifactId等参数),在我们运行这个goal的时候maven根据标准配置生成了一个控制台程序。
maven的plugin是一系列goal的集合,并且plugin是可扩展的,所以我们可以执行很多的任务而不需要自己去编写配置文件(因为插件是可下载的)。
3.4.2 关于打包
我们“3.3 编译”小节打包的时候运行的mvn package命令,只是一个简单的工程构建生命周期中的一个命令,我们称之为一个阶段(phase)。这个需要和goal区分开来。工程的构建生命周期就是由一系列的phase构成的。
当给出一个阶段时,maven将执行所有之前的phase及自身。
这里可能不是很容易理解,那么我们做个类比:Android开发中自动化构建打包我们需要执行很多个步骤(可以参见Android学习之Build.xml文件),那么这些步骤就可以看成是一个个的phase,只不过maven提供了一些默认的phase。
4. 生命周期
既然有阶段,那么对应的每个工程在构建过程中会有生命周期(Life Cycle)的概念。由于工程的类型形形色色,那么必然对应不同的生命周期,我们列举一个典型的J2EE项目的生命周期表:
validate | 校验工程的正确性。主要检查相关资源、依赖项等。 |
compile | 编译项目的源代码。 |
test | 执行单元测试。 |
package | 打包。 |
integration-test | 集成测试。将包发布到测试环境。 |
verify | 检查包是否达到发布标准。 |
install | 把包安装到本地仓库中,这样可以被其他工程作为依赖项使用。 |
deploy | 发布到远程仓库,这样可被其他工程共享使用。 |
clean | 清除之前生成的artifact。比如可以清除我们package生成的内容。 |
site | 生成站点。 |
那么我们下面看看Life Cycle、Phase、Goal的关系:
- Life Cycle是多个Phase的集合;
- 每个Phase实际上都对应一个Goal,项目类型不同,对应的Goal也不尽相同。例如如果项目类型是jar,那么在package阶段应该执行的goal是jar:jar;如果项目类型是war,那么package阶段执行的goal应该是war:war。