Maven,发音是[`meivin],”专家”的意思。写这个学习笔记的目的,1个是为了自己备忘,2则希望能够为其他人学习使用maven缩短1些时间。
maven是甚么 |
maven将自己定位为1个项目管理工具。它负责管理项目开发进程中的几近所有的东西:
版本
maven有自己的版本定义和规则
构建
maven支持许多种的利用程序类型,对每种支持的利用程序类型都定义好了1组构建规则和工具集。
输出管理
maven可以管理项目构建的产物,并将其加入到用户库中。这个功能可以用于项目组和其他部门之间的交付行动。
依赖关系
maven对依赖关系的特性进行细致的分析和划分,避免开发进程中的依赖混乱和相互污染行动
文档和构建结果
maven的site命令支持各种文档信息的发布,包括构建进程的各种输出,javadoc,产品文档等。
项目关系
1个大型的项目通常有几个小项目或模块组成,用maven可以很方便地管理
移植性管理
maven可以针对不同的开发场景,输出不同种类的输出结果。
maven的生命周期 |
Maven有3套相互独立的生命周期,分别是clean、default和site。每一个生命周期包括1些阶段(phase),阶段是有顺序的,后面的阶段依赖于前面的阶段。
1、clean生命周期:清算项目,包括3个phase:
1)pre-clean:履行清算前需要完成的工作
2)clean:清算上1次构建生成的文件
3)post-clean:履行清算后需要完成的工作
2、default生命周期:构建项目,重要的phase以下
1)validate:验证工程是不是正确,所有需要的资源是不是可用。
2)compile:编译项目的源代码。
3)test:使用适合的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。
4)Package:把已编译的代码打包成可发布的格式,比如jar。
5)integration-test:如有需要,将包处理和发布到1个能够进行集成测试的环境。
6)verify:运行所有检查,验证包是不是有效且到达质量标准。
7)install:把包安装到maven本地仓库,可以被其他工程作为依赖来使用。
8)deploy:在集成或发布环境下履行,将终究版本的包拷贝到远程的repository,使得其他的开发者或工程可以同享。
3、site生命周期:建立和发布项目站点,phase以下:
1)pre-site:生成项目站点之前需要完成的工作
2)site:生成项目站点文档
3)post-site:生成项目站点以后需要完成的工作
4)site-deploy:将项目站点发布到服务器
maven中所有的履行动作(goal)都需要指明自己在这个进程中的履行位置,然后maven履行的时候,就依照进程的发展顺次调用这些goal进行各种处理。这个也是maven的1个基本调度机制。1般来讲,位置稍后的进程都会依赖于之前的进程。固然,maven一样提供了配置文件,可以依照用户要求,跳过某些阶段。
maven的”约定优于配置” |
所谓的”约定优于配置”,在maven中其实不是完全不可以修改的,他们只是1些配置的默许值而已。但是使用者除非必要,其实不需要去修改那些约定内容。maven默许的文件寄存结构以下:
/项目目录
pom.xml 用于maven的配置文件
/src 源代码目录
/src/main 工程源代码目录
/src/main/java 工程java源代码目录
/src/main/resource 工程的资源目录
/src/test 单元测试目录
/src/test/java
/target 输出目录,所有的输出物都寄存在这个目录下
/target/classes 编译以后的class文件
每个阶段的任务都知道怎样正确完成自己的工作,比如compile任务就知道从src/main/java下编译所有的java文件,并把它的输出class文件寄存到target/classes中。
对maven来讲,采取”约定优于配置”的策略可以减少修改配置的工作量,也能够下降学习本钱,更重要的是,给项目引入了统1的规范。
maven的版本规范 |
maven使用以下几个要夙来唯1定位某1个输出: groupId:artifactId:packaging:version。比如org.springframework:spring:2.5。每一个部份的解释以下:
团体,公司,小组,组织,项目,或其它团体。团体标识的约定是,它以创建这个项目的组织名称的逆向域名(reverse domainname)开头。来自Sonatype的项目有1个以com.sonatype开头的groupId,而ApacheSoftware的项目有以org.apache开头的groupId。
在groupId下的表示1个单独项目的唯1标识符。比如我们的tomcat, commons等。不要在artifactId中包括点号(.)。
1个项目的特定版本。发布的项目有1个固定的版本标识来指向该项目的某1个特定的版本。而正在开发中的项目可以用1个特殊的标识,这类标识给版本加上1个”SNAPSHOT”的标记。
虽然项目的打包格式也是Maven坐标的重要组成部份,但是它不是项目唯1标识符的1个部份。1个项目的groupId:artifactId:version使之成为1个唯一无2的项目;你不能同时有1个具有一样的groupId,artifactId和version标识的项目。
项目的类型,默许是jar,描写了项目打包后的输出。类型为jar的项目产生1个JAR文件,类型为war的项目产生1个web利用。
很少使用的坐标,1般都可以疏忽classifiers。如果你要发布一样的代码,但是由于技术缘由需要生成两个单独的构件,你就要使用1个分类器(classifier)。例如,如果你想要构建两个单独的构件成JAR,1个使用Java 1.4编译器,另外一个使用Java6编译器,你就能够使用分类器来生成两个单独的JAR构件,它们有一样的groupId:artifactId:version组合。如果你的项目使用本地扩大类库,你可使用分类器为每个目标平台生成1个构件。分类器经常使用于打包构件的源码,JavaDoc或2进制集合。
maven有自己的版本规范,1般是以下定义 ..-,比如1.2.3-beta-01。要说明的是,maven自己判断版本的算法是major,minor,incremental部份用数字比较,qualifier部份用字符串比较,所以要谨慎 alpha⑵和alpha⑴5的比较关系,最好用 alpha-02的格式。
maven在版本管理时候可使用几个特殊的字符串 SNAPSHOT,LATEST,RELEASE。比如”1.0-SNAPSHOT”。各个部份的含义和处理逻辑以下说明:
如果1个版本包括字符串”SNAPSHOT”,Maven就会在安装或发布这个组件的时候将该符号展开为1个日期和时间值,转换为UTC时间。例如,”1.0-SNAPSHOT”会在2010年5月5日下午2点10分发布时候变成1.0⑵0100505⑴41000⑴。
这个词只能用于开发进程中,由于1般来讲,项目组都会频繁发布1些版本,最后实际发布的时候,会在这些snapshot版本中寻觅1个稳定的,用于正式发布,比如1.4版本发布之前,就会有1系列的1.4-SNAPSHOT,而实际发布的1.4,也是从中拿出来的1个稳定版。
指某个特定构件的最新发布,这个发布多是1个发布版,也多是1个snapshot版,具体看哪一个时间最后。
指最后1个发布版。
maven的组成部份 |
maven把全部maven管理的项目分为几个部份,1个部份是源代码,包括源代码本身(src/java)、相干的各种资源(src/resources),1个部份则是单元测试用例(test),另外1部份则是各种maven的插件。对这几个部份,maven可以独立管理他们,包括各种外部依赖关系。
maven的依赖管理 |
依赖管理1般是最吸引人使用maven的功能特性了,这个特性让开发者只需要关注代码的直接依赖,比如我们用了spring,就加入spring依赖说明就能够了,至于spring自己还依赖哪些外部的东西,maven帮我们弄定。
任意1个外部依赖说明包括以下几个要素:groupId, artifactId, version, scope, type, optional。其中前3个是必须的,各自含义以下:
groupId | 必须 |
---|---|
artifactId | 必须 |
version | 必须 (这里的version可以用区间表达式来表示,比如(2.0,)表示>2.0,[2.0,3.0)表示2.0<=ver<3.0;多个条件之间用逗号分隔,比如[1,3),[5,7]。) |
scope:作用域限制
type:1般在pom援用依赖时候出现,其他时候不用
optional:是不是可选依赖
maven认为,程序对外部的依赖会随着程序的所处阶段和利用场景而变化,所以maven中的依赖关系有作用域(scope)的限制。在maven中,scope包括以下的取值:
compile(编译范围)
compile是默许的范围;如果没有提供1个范围,那该依赖的范围就是编译范围。编译范围依赖在所有的classpath中可用,同时它们也会被打包。
provided(已提供范围)
provided依赖只有在当JDK或1个容器已提供该依赖以后才使用。例如,如果你开发了1个web利用,你可能在编译classpath中需要可用的Servlet API来编译1个servlet,但是你不会想要在打包好的WAR中包括这个Servlet API;这个Servlet API JAR由你的利用服务器或servlet容器提供。已提供范围的依赖在编译classpath(不是运行时)可用。它们不是传递性的,也不会被打包。
runtime(运行时范围)
runtime依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。
test(测试范围)
test范围依赖在1般的编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。
system(系统范围)
system范围依赖与provided类似,但是你必须显式的提供1个对本地系统中JAR文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库的1部份。这样的构件应当是1直可用的,Maven也不会在仓库中去寻觅它。 如果你将1个依赖范围设置成系统范围,你必须同时提供1个systemPath元素 。注意该范围是不推荐使用的(你应当1直尽可能去从公共或定制的Maven仓库中援用依赖)。
另外,代码有代码自己的依赖,各个maven使用的插件也能够有自己的依赖关系。依赖也能够是可选的,比如我们代码中没有任何cache依赖,但是hibernate可能要配置cache,所以该cache的依赖就是可选的。
maven的多项目管理 |
maven的多项目管理也是非常强大的。1般来讲,maven要求同1个工程的所有子项目都放置到同1个目录下,每个子目录代表1个项目,比如
总项目/
pom.xml 总项目的pom配置文件
子项目1/
pom.xml 子项目1的pom文件
子项目2/
pom.xml 子项目2的pom文件
依照这类格式寄存,就是继承方式,所有具体子项目的pom.xml都会继承总项目pom的内容,取值为子项目pom内容优先。
要设置继承方式,首先要在总项目的pom中加入以下配置
<modules>
<module>simple-webapp01</module>
<module>simple-webapp02</module>
</modules>
其次在每一个子项目中加入
<parent>
<groupId>org.sonatype.mavenbook.ch06</groupId>
<artifactId>simple-parent</artifactId>
<version>1.0</version>
</parent>
便可。
固然,继承不是唯1的配置文件共用方式,maven还支持援用方式。援用pom的方式更简单,在依赖中加入1个type为pom的依赖便可。
<project>
<description>This is a project requiring JDBC</description>
...
<dependencies>
...
<dependency>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>persistence-deps</artifactId>
<version>1.0</version>
<type>pom</type> <----------------->
</dependency>
</dependencies>
</project>
用户可以在maven中定义1些属性,然后在其他地方用${xxx}进行援用。比如:
<project>
<modelVersion>4.0.0</modelVersion>
...
<properties>
<var1>value1</var1>
</properties>
</project>
maven提供了3个隐式的变量,用来访问系统环境变量、POM信息和maven的settings:
env
暴露操作系统的环境变量,比如env.PATH
project
暴露POM中的内容,用点号(.)的路径来援用POM元素的值,比如${project.artifactId}。另外,java的系统属性比如user.dir等,也暴露在这里。
settings
暴露maven的settings的信息,也能够用点号(.)来援用。maven把系统配置文件寄存在maven的安装目录中,把用户相干的配置文件寄存在~/.m2/settings.xml(unix)或%USERPROFILE%/.m2/settings.xml(windows)中。
maven的profile |
profile是maven的1个重要特性,它可让maven能够自动适应外部的环境变化,比犹如1个项目,在linux下编译linux的版本,在win下编译win的版本等。1个项目可以设置多个profile,也能够在同1时间设置多个profile被激活(active)的。自动激活的profile的条件可以是各种各样的设定条件,组合放置在activation节点中,也能够通过命令行直接指定。profile包括的其他配置内容可以覆盖掉pom定义的相应值。如果认为profile设置比较复杂,可以将所有的profiles内容移动到专门的 profiles.xml 文件中,不过记得和pom.xml放在1起。
activation节点中的激活条件中常见的有以下几个:
os - 判断操作系统相干的参数,它包括以下可以自由组合的子节点元素
message - 规则失败以后显示的消息
arch - 匹配cpu结构,常见为x86
family - 匹配操作系统家族,常见的取值为:dos,mac,netware,os/2,unix,windows,win9x,os/400等
name - 匹配操作系统的名字
version - 匹配的操作系统版本号
display - 检测到操作系统以后显示的信息
jdk
检查jdk版本,可以用区间表示。
property
检查属性值,本节点可以包括name和value两个子节点。
file
检查文件相干内容,包括两个子节点:exists和missing,用于分别检查文件存在和不存在两种情况。
maven的使用 |
maven上手很快,经常使用的1些安装配置也比较简单,但是要找到1些比较稳定和强大的maven库。在1般的开发中,maven都是作为插件在eclipse中或是其他的IDE环境中去使用,摁钉(ending)!!!