没有使用maven的时候,我们在项目开始就要下载各种jar包,Spring、mybatis等等。
maven作为一个构建工具,能帮助我们标准化构建流程,有了maven之后,所有项目的构建命令都是一致的,这能避免很多学习成本。
maven主要解决这几个问题:
maven的中心思想是POM文件(项目对象模型)。POM文件是以XML文件的形式表述项目的资源,如源码、测试代码、依赖(用到的外部Jar包)等。POM文件应该位于项目的根目录下。
通过pom.xml对jar包进行集中管理。Maven工程不用手动导jar包,通过在pom.xml中定义坐标从maven仓库自动下载,方便且不易出错。
当执行maven命令的时候,会传入一个pom文件,maven会在pom文件的描述上进行依赖下载,执行生命周期,最后执行插件的构建任务,构建插件可以向构建阶段中增加额外的构建目标。
POM文件描述的是构建什么。
一个项目如果分为多个子项目,一般来讲,父项目有一个POM文件,每一个子项目都有一个POM文件。在这种结构下,既可以一步构建整个项目,也可以各个子项目分开构建。
一个最小化的POM文件示例:
4.0.0
com.sysuzhyupeng
java-web-project
1.0.0
modelVersion属性表示使用的POM模型的版本。选择和你正在使用的Maven版本一致的版本即可。版本4.0.0适用于Maven 2和3。
groupId/artifactId/version代表一个项目的坐标,用于唯一定位一个项目。groupId,artifactId和version属性,在项目构建后会生成一个jar文件,位于Maven仓库的如下路径中(目录和文件名):MAVEN_REPO/com/sysuzhyupeng/java-web-crawler/1.0.0/java-web-project-1.0.0.jar
packaging定义maven项目的打包方式,决定打包成jar或者war包(web工程)等。
所有的Maven pom文件都继承自一个父pom。如果没有指定父pom,则该pom文件继承自根pom。
可以让一个pom文件显式地继承另一个pom文件。这样,可以通过修改公共父pom文件的设置来修改所有子pom文件的设置。在pom文件的起始处指定父pom
com.taobao
parent
2.0.0
子pom文件的设置可以覆盖父pom文件的设置,只需要在子pom文件里指定新的设置即可。
运行Maven只需在命令行执行mvn
命令即可。当执行mvn
命令时,将构建周期、阶段或目标作为参数传进去,Maven就会执行它们。例如:
mvn install
你可以向mvn命令传入多个参数,执行多个构建周期或阶段,如:
mvn clean install
该命令首先执行clean构建周期,删除Maven输出目录中已编译的类文件,然后执行install构建阶段。
Maven的本地仓库默认在你本机的用户目录下。
Maven的中央仓库由Maven社区提供。默认情况下,所有不在本地仓库中的依赖都会去这个中央仓库查找。然后Maven会将这些依赖下载到你的本地仓库。访问中央仓库不需要做额外的配置。
远程仓库是位于web服务器上的一个仓库,Maven可以从该仓库下载依赖,就像从中央仓库下载依赖一样。远程仓库可以位于Internet上的任何地方,也可以是位于本地网络中。远程仓库中的依赖也会被Maven下载到本地仓库中。
可以在pom文件里配置远程仓库。将以下的xml片段放到属性之后:
jenkov.code
http://maven.sysuzhyupeng.com/maven2/lib
在dependencies属性下有两个dependency子属性,每一个dependency属性描述了一个外部依赖。
junit
junit
4.8.1
test
每一个依赖由groupId, artifactId和version来描述。这里的示例为junit组织下的4.8.1版本的junit。上面示例中的两个依赖将会被放到以下子目录中MAVEN_REPOSITORY_ROOT/junit/junit/4.8.1。
有的时候,指定的依赖在Maven的中央仓库里没有。你可以直接下载这些依赖,然后放到Maven的本地仓库。这些依赖必须放到与groupId、 artifactId和version匹配的子目录中。用/替换所有的点(.)并且使用/分隔groupId、artifactId和version,这 就是与该依赖匹配的子目录。
Maven的外部依赖指的是不在Maven的仓库(包括本地仓库、中央仓库和远程仓库)中的依赖(jar包)。
配置外部依赖的示例如下:
mydependency
mydependency
system
1.0
${basedir}\war\WEB-INF\lib\mydependency.jar
groupId和artifactId为依赖的名称,即API的名称。scope属性为system。systemPath属性为jar文件的路径。${basedir}为pom文件所在的目录,路径中的其它部分是相对于该目录而言的。
快照依赖指的是那些还在开发中的依赖(jar包)。与其经常地更新版本号来获取最新版本,不如你直接依赖项目的快照版本。
在pom文件的最开头(设置groupId和artifactId的地方),在版本号后追加-SNAPSHOT,则告诉Maven你的项目是一个快照版本。如:
com.sysuzhyupeng
java-web-project
1.0-SNAPSHOT
Maven有三个内嵌的构建生命周期:
每一个构建生命期关注项目构建的不同方面。因此,它们是独立地执行的。Maven可以执行多个生命期,但是它们是串行执行的,相互独立,就像你执行了多条独立的Maven命令。
default生命期关注的是项目的编译和打包。clean生命期关注的是从输出目录中删掉临时文件,包括自动生成的源文件、编译后的类文件,之前版本的jar文件等。site生命期关注的是为项目生成文档。实际上,site可以使用文档为项目生成一个完整的网站。
default生命期中有这几个值得关注:
当项目A中有这样的依赖关系: A - B - C - X(1.0)和A - D - X(2.0), X是A的传递性依赖,但是这两条依赖路径上有两个版本的X,maven依赖调解的第一个原则是路径短的优先,那么2.0会被解析使用。
在相同路径长度的情况下,在POM中依赖声明的顺序决定了谁会被解析使用。(第一声明优先原则)
可选依赖:当A - B, B - X(可选),B - Y(可选)。依赖将不会被传递。当X和Y是两个互斥的依赖的时候,可选的依赖就起到了作用。这时候A就可以声明要依赖X或者Y。
排除依赖:当A - B,B - C,当A不想引入C的时候,可以在声明B的时候排除依赖C