Maven知识概括
Maven介绍
为什么需要Maven?
添加第三方 jar包
①在今天的 JavaEE 开发领域,有大量的第三方框架和工具可以供我们使用。要使用这些 jar 包最简单的方法就是复制粘贴到 WEB-INF/lib 目录下。但是这会导致每次创建一个新的工程就需要将 jar 包重复复制到 lib 目录下,从而造成工作区中存在大量重复的文件,让我们的工程显得很臃肿。而使用 Maven 后每个 jar 包本身只在本地仓库中保存一份,需要 jar 包的工程只需要以坐标的方式简单的引用一下就可以了。不仅极大的节约了存储空间,让项目更轻巧,更避免了重复文件太多而造成的混乱。jar 包之间的依赖关系
①jar 包往往不是孤立存在的,很多 jar 包都需要在其他 jar 包的支持下才能够正常工作,我们称之为
jar 包之间的依赖关系。最典型的例子是:commons-fileupload-1.3.jar 依赖于 commons-io-2.0.1.jar,如果没有 IO 包,FileUpload 包就不能正常工作。
②那么问题来了,你知道你所使用的所有 jar 包的依赖关系吗?当你拿到一个新的从未使用过的 jar包,你如何得知他需要哪些 jar 包的支持呢?如果不了解这个情况,导入的 jar 包不够,那么现有的程序将不能正常工作。再进一步,当你的项目中需要用到上百个 jar 包时,你还会人为的,手工的逐一确认它们依赖的其他 jar 包吗?这简直是不可想象的。
③而引入 Maven 后,Maven 就可以替我们自动的将当前 jar 包所依赖的其他所有 jar 包全部导入进来,无需人工参与,节约了我们大量的时间和精力。用实际例子来说明就是:通过 Maven 导入
commons-fileupload-1.3.jar 后,commons-io-2.0.1.jar 会被自动导入,程序员不必了解这个依赖关系。
④下图是 Spring 所需 jar 包的部分依赖关系:
获取第三方 jar 包
①JavaEE 开发中需要使用到的 jar 包种类繁多,几乎每个 jar 包在其本身的官网上的获取方式都不尽相同。为了查找一个 jar 包找遍互联网,身心俱疲,没有经历过的人或许体会不到这种折磨。不仅如此,费劲心血找的 jar 包里有的时候并没有你需要的那个类,又或者又同名的类没有你要的方法——以不规范的方式获取的 jar 包也往往是不规范的。
②使用 Maven 我们可以享受到一个完全统一规范的 jar 包管理体系。你只需要在你的项目中以坐标的方式依赖一个 jar 包,Maven 就会自动从中央仓库进行下载,并同时下载这个 jar 包所依赖的其他 jar 包——规范、完整、准确!一次性解决所有问题!
③Tips:在这里我们顺便说一下,统一的规范几乎可以说成是程序员的最高信仰。如果没有统一的规范,就意味着每个具体的技术都各自为政,需要以诸多不同的特殊的方式加入到项目中;好不容易加入进来还会和其他技术格格不入,最终受苦的是我们。而任何一个领域的统一规范都能够极大的降低程序员的工作难度,减少工作量。例如:USB 接口可以外接各种设备,如果每个设备都有自己独特的接口,那么不仅制造商需要维护各个接口的设计方案,使用者也需要详细了解每个设备对应的接口,无疑是非常繁琐的。将项目拆分成多个工程模块
①随着 JavaEE 项目的规模越来越庞大,开发团队的规模也与日俱增。一个项目上千人的团队持续开发很多年对于 JavaEE 项目来说再正常不过。那么我们想象一下:几百上千的人开发的项目是同一个 Web工程。那么架构师、项目经理该如何划分项目的模块、如何分工呢?这么大的项目已经不可能通过package 结构来划分模块,必须将项目拆分成多个工程协同开发。多个模块工程中有的是 Java 工程,有的是 Web 工程。
②那么工程拆分后又如何进行互相调用和访问呢?这就需要用到 Maven 的依赖管理机制。大家请看 我们的 Survey 调查项目拆分的情况:
<1>上层模块依赖下层,所以下层模块中定义的 API 都可以为上层所调用和访问。
什么是Maven:
- Maven 是 Apache 软件基金会组织维护的一款自动化构建工具,专注服务于 Java 平台的项目构建和 依赖管理。Maven这个单词的本意是:专家,内行。
市场流行构建工具:Make→Ant→Maven→Gradle
构建简介
构建简介:
构建并不是创建,创建一个工程并不等于构建一个项目。要了解构建的含义我们应该由浅入深的从 以下三个层面来看:
纯 Java 代码:
①大家都知道,我们 Java 是一门编译型语言,.java 扩展名的源文件需要编译成.class 扩展名的字节码文件才能够执行。所以编写任何 Java 代码想要执行的话就必须经过编译得到对应的.class 文件。Web 工程:
①当我们需要通过浏览器访问 Java 程序时就必须将包含 Java 程序的 Web 工程编译的结果“拿”到服务器上的指定目录下,并启动服务器才行。这个“拿”的过程我们叫部署。
②我们可以将未编译的 Web 工程比喻为一只生的鸡,编译好的 Web 工程是一只煮熟的鸡,编译部署的过程就是将鸡炖熟。
③Web 工程和其编译结果的目录结构对比见下图:
实际项目:
①在实际项目中整合第三方框架,Web 工程中除了 Java 程序和 JSP 页面、图片等静态资源之外,还包括第三方框架的 jar 包以及各种各样的配置文件。所有这些资源都必须按照正确的目录结构部署到服务器上,项目才可以运行。- 所以综上所述:
构建就是以我们编写的 Java 代码、框架配置文件、国际化等其他资源文件、JSP 页面和图片等静态资源作为“原材料”,去“生产”出一个可以运行的项目的过程。
构建过程各个环节简述:
- 清理:删除以前的编译结果,为重新编译做好准备。
- 编译:将 Java 源程序编译为字节码文件。
- 测试:针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。
- 报告:在每一次测试后以标准的格式记录和展示测试结果。
- 打包:将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java 工程对应 jar 包,Web 工程对应 war 包。
- 安装:在 Maven 环境下特指将打包的结果——jar 包或 war 包安装到本地仓库中。
①在本地repository中安装jar(包含mvn compile,mvn package,然后上传到本地仓库)
- 部署:将打包的结果部署到远程仓库或将 war 包部署到服务器上运行。
①上传到私服(包含mvn install,然后,上传到私服)
自动化构建:
- 就是将上述的编译,测试,报告,打包,安装,部署这些工作交给机器完成。
项目为什么要使用jar或war进行打包发布?区别是什么?
- 在做项目时,通常对即将要发布的项目打成两种类型的包:
①jar
②war
- 一般将项目分为两层:
服务层和表现层(视图层)
。
①把服务层打包成jar包
,
②把视图层的包打成war包
。 - 通过仔细对比可以发现:
①jar包中包含了你写程序的所有服务或者第三方类库
,它通常是作为幕后工作者,为视图层用户与之交换数据处理的一个服务者,jar文件格式以Zip文件格式为基础,与Zip不同的是,它可以被发布,而且还能用于部署,它封装了库、组件和插件程序,并且可以被编译器和jvm使用,在jar中还包含特殊的文件,如mainfests和部署的应用描述,用于指示工具如何处理特定的jar。
②一个war文件可以看成一个web应用程序
。与jar封装不同的是:它内聚了很多页面,如html、jsp,Servlet,js,css,icon图片文件等等,当然还包括组成web应用的其他组件,这些文件基本没有复杂业务逻辑的处理,基本上仅仅是用来当做程序的门户负责与使用者交互,仅此而已。 - 这样做有什么好处呢?
①这样做使代码的层次分明,前后端分离;
②便于划清前后端的职责,加快开发进度并且利于维护;
③对于靠后期维护的项目来说,比如业务复杂多变而又琐碎的项目,如果仅仅是改变前端的样式或者进行调整,我不必把服务也关掉,只需要停掉web,做完修改后能够马上部署上线。
<1>针对我写过的项目来说,直接调用接口给到的返回结果可以根据需要只在页面进行调用就能够显示,而服务端代码一点都不需要变化,极大方便了开发。
<2>使用了springboot后,项目都会被打包成jar,或者打包成war部署在外部容器中也可以。 - 以上都是从实际中出发看出的最明显的区别,如果从内部看可以看到:
①war包中的目录结构中包括WEB-INF,而war是一个可以直接运行的web模块,做好一个web项目后,需要打包部署到容器中,一般放置在tomcat的\webapps\目录下,当启动tomcat时,这个包将被解压,即相当于发布了。
②jar中一般都是些class文件,声明了Main_cass后就可以用java命令去运行它。
③所有的包都是用jar打的,只不过目标文件的扩展名不一样。与jar类似,war也是许多文件的一个压缩包。这个包中的文件按一定目录结构来组织:通常其根目录下包含之前所说的有Html和Jsp文件或者包含这两种文件的目录,另外还会有一个WEB-INF目录,通常在WEB-INF目录下有一个web.xml文件和一个classes目录,web.xml是这个应用的配置文件,而classes目录下则包含编译好的Servlet类和Jsp或Servlet所依赖的其它类(如JavaBean)。
④通常这些所依赖的类也可以打包成JAR放到WEB-INF下的lib目录下,当然也可以放到系统的CLASSPATH中,但那样移植和管理起来不方便。
配置Maven环境变量
简述:
- Path环境变量
- MAVEN_HOME环境变量
- 运行mvn -v命令查看Maven版本
Maven 核心概念
约定的目录结构简述:
- 约定的目录结构对于 Maven 实现自动化构建而言是必不可少的一环,就拿自动编译来说,Maven 必须 能找到 Java源文件,下一步才能编译,而编译之后也必须有一个准确的位置保持编译得到的字节码文件。
- 我们在开发中如果需要让第三方工具或框架知道我们自己创建的资源在哪,那么基本上就是两种方式:
①通过配置的形式明确告诉它
②基于第三方工具或框架的约定
Maven 对工程目录结构的要求就属于后面的一种。
- 现在 JavaEE开发领域普遍认同一个观点:约定>配置>编码。意思就是能用配置解决的问题就不编码,能基于约定的就不进行配置。而 Maven正是因为指定了特定文件保存的目录才能够对我们的 Java 工程进行自动化构建。
Maven项目和Java项目本质上没区别,且Maven项目里的子父项目无区别,本质上都是通过Jar包引用。
常用的Maven命令简述:
- 注意:执行与构建过程相关的Maven命令。必须进入pom.xml所在的目录。
- 常用命令:
①mvn clean:清理,将根目录下生成的target文件移除。
②mvn compile:编译主程序
③mvn test-compile :编译测试程序
④mvn test:执行测试
⑤mvn package:编译代码并打包
⑥mvn install:编译代码并打包、将打好的包放置到本地仓库中(如果还是同一个版本默认会覆盖之前安装的包)
⑦mvn site:生成站点,用户可以让Maven自动生成一个Web站点,以Web的形式发布如项目描述、版本控制系统地址、缺陷跟踪系统地址等,更便捷、更快速地为团队提供项目当前的状态信息。
Maven联网的问题简述:
Maven的核心程序中仅仅定义了抽象的生命周期
。但是具体的工作必须由特点的插件来完成。而插件本身并不包含在Maven的核心程序中。
- 当我们执行的Maven命令需要用到某些插件时,Maven核心程序会首先到本地仓库中查询。
- 本地仓库的默认位置:[系统中当前用户的家目录].m2\repository
例如:C:\Users[登录当前系统的用户名].m2\repository - Maven核心程序如果在本地仓库找不到需要的插件,那么它会自动连接外网到中央仓库去下载。
- 如果此时无法连接外网,则构建失败。
- 修改默认的本地仓库的位置可以让Maven核心程序到我们事先准备好的目录下去查找插件。
①找到Maven解压目录\conf\setting.xml
②在setting.xml文件中找到localRepostiory
③将<localRepostiory>/path/to/local/repo</localRepostiory>从注释中取出
④将标签体内容修改为已经准备好的Maven仓库目录。
例如:<localRepostiory>D:\RepMaven</localRepostiory>
POM简述:
Project Object Model:项目对象模型。
将 Java 工程的相关信息封装为对象作为便于操作和管理的模型。- Maven 工程的核心配置。
可以说学习 Maven 就是学习 pom.xml 文件中的配置。
Maven坐标:
- 几何中的坐标:
①在一个平面中使用 x、y 两个向量可以唯一的确定平面中的一个点。
②在空间中使用 x、y、z 三个向量可以唯一的确定空间中的一个点 - Maven 的坐标:
①使用如下三个向量在 Maven 的仓库中唯一的确定一个 Maven 工程。
<1>groupid:公司或组织的域名倒序+当前项目名称
: <groupId>>com.atguigu.maven</groupId>>
<2>artifactId:当前项目的模块名称
: <artifactId>Hello</artifactId>
<3>version:当前模块的版本
: <version>0.0.1-SNAPSHOT</version>
Snapshot版本和release版本区别:
- 一般来说snapshots版本代表正在开发中的版本,release代表比较稳定的发布版本.
- 比如我们新建一个maven项目,默认版本是这样的:
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project</description>
- 上面0.0.1表示项目的版本号,表示这次迭代我要开发的所有主要功能都是属于这个版本的;
- -SNAPSHOT表示该版本是快照版本,一般处于开发阶段,0.0.1版本还有功能没有完成,或还有bug还要修复,所以这个阶段一般代码更新比较频繁,开发人员写完代码会直接提交到代码仓库,这样之前依赖0.0.1-SNAPSHOT版本的开发人员也可以马上更新代码.
- -Release表示是稳定版的,这次迭代的所有功能都已经完成,并且通过了测试之后,就可以发布为0.0.1-Release版本,Release版的一旦发布,就不要再改变代码了,所以如果之后在0.0.1-Release这个版本上发现了bug,需要修复,那么我们应该将0.0.1-Release版本改为0.0.2-SNAPSHOT,然后再修改bug并测试,没问题之后将0.0.2-SNAPSHOT改为0.0.2-Release发布.
- 使用maven的时候maven会根据pom文件中的version中是否带有-SNAPSHOT来判断是否是快照版本。如果是快照版本,在maven deploy时会发布到快照版本库中,依赖该版本的项目在编译打包时,maven会自动从maven仓库下载新的快照版本。如果是正式发布版本,deploy时会自动发布到正式版本库中,依赖该版本的项目在编译打包时如果本地已经存在该版本的工程默认不会从maven仓库下载新的版本.
- 所以如果现在开发的项目依赖了另外一个项目,如果不希望出现本来运行的好好地,过了一会儿因为依赖项目的更新突然不能运行了,那么可以选择依赖一个Release版本(如果有的话).
仓库简介:
- 仓库分类:
①本地仓库:为当前本机电脑上的所有 Maven 工程服务。
②远程仓库:
<1>私服:架设在当前局域网环境下,为当前局域网范围内的所有 Maven 工程服务。
1、我们在实际的项目中通常使用私服来间接访问中央仓库,项目通常不直接访问中央仓库。
2、在私服中我们以nexus为主
<2>中央仓库:架设在 Internet 上,为全世界所有 Maven 工程服务。
<3>中央仓库的镜像:架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响应用户请求。
- 仓库中的文件:
①Maven 的插件
②我们自己开发的项目的模块
③第三方框架或工具的 jar 包
- 注意:
①不管是什么样的 jar 包,在仓库中都是按照坐标生成目录结构,所以可以通过统一的方式查询或依赖。
②我们自己的 Maven 工程必须执行安装操作才会进入仓库。
<1>安装的命令是:mvn install
依赖
依赖的目的是什么:
- 当 A jar 包用到了 B jar 包中的某些类时,A 就对 B 产生了依赖,这是概念上的描述。在项目中使用 dependency标签指定被依赖 jar 包的坐标的方式引入一个我们需要的 jar 包。
<dependency>
<groupId>com.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
依赖的寻找方式:
-
当引入父项目时:
①Maven首先在构建当前项目的地方寻找父项目的pom。
②其次在文件系统的这个位置(relativePath位置)。
③然后在本地仓库。
④最后在远程仓库寻找父项目的pom。 -
当引入普通项目时:
①首先在构建当前项目的地方寻找项目的jar或者war包。(注意:只有加入maven project的才算)
②其次在然后在本地仓库寻找。
③最后在远程仓库寻找。
依赖的范围:
- 依赖信息中除了目标 jar 包的坐标还有一个 scope 设置,这是依赖的范围。依赖的范围有compile、test、provided三个。
compile范围依赖:
①对主程序是否有效:有效
②对测试程序是否有效:有效
③是否参与打包:参与
④是否参与部署:参与
⑤例如:spring-coretest范围依赖:
①对主程序是否有效:无效
②对测试程序是否有效:有效
③是否参与打包:不参与
④是否参与部署:不参与
⑤例如:junitprovided范围依赖:
provided意味着打包的时候可以不用包进去,别的设施(Web Container)会提供。
①对主程序是否有效:有效
②对测试程序是否有效:有效
③是否参与打包:不参与
④是否参与部署:不参与
⑤例如:servlet-api.jar,jsp-api.jar
runntime范围依赖:
runntime表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与,与compile相比,跳过编译而已。比如你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。
①对主程序是否有效:无效
②对测试程序是否有效:有效
③是否参与打包:参与
④是否参与部署:参与
Maven依赖的optional元素:
假如你的Project A的某个依赖D添加了
:<optional>true</optional>
,当别人通过pom依赖ProjectA的时候,D不会被传递依赖进来
- 当你依赖某各工程很庞大或很可能与其他工程的jar包冲突的时候建议加上该选项,可以节省开销,同时减少依赖冲突
默认为不去除:
①在项目中设optional为false
②去除optional
maven面板冲突的特征:
依赖传递性:
- 好处:可以传递的依赖不必在每个模块中都重复声明,在“最下面”的工程中依赖一次即可。
- 注意:
非complie范围的依赖不能传递
,所以在各个工程模块中,如果有需要就得重复声明依赖。`
- 链接:Maven依赖规则和依赖范围
依赖排除:
- 设置依赖排除的场合:
- 依赖排除的设置方式:
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
依赖的原则:
- 作用:解决模块工程之间的jar包冲突问题。
- 情景①:
路径最短者优先原则:
- 情景②:
路径相同时先声明者优先:
统一管理所依赖的版本:
- 情景举例:
①这里对Spring各个jar包的依赖版本都是4.0.0
②如果需要统一升级为4.1.1,手动逐一修改太麻烦。
- 建议配置方式:
一、使用properties标签呃逆使用自定义标签统一声明版本号。
<properties>
<spring-version>4.0.0.RELEASE</spring-version>
</properties>
二、在需要统一版本的位置,使用$()引用声明的版本号。
<version>$(spring-version)</version>
- 其实properties标签配合自定义标签生命数据的配置并不只是用于声明依赖的版本号,凡是需要统一声明后再引用的场合都可以使用。
继承简介:
- 为什么需要继承机制:
①由于非 compile 范围的依赖信息是不能在“依赖链”中传递的,所以有需要的工程只能单独配置
。
②此时如果项目需要将各个模块的版本统一为某个版本,那么到各个工程中手动修改无疑是非常麻烦的。
③使用继承机制就可以将这样的依赖信息统一提取到父工程模块中进行统一管理。
- 此外在多层继承中若中间的pom设置了某个jar包的版本号则会覆盖其父链pom的版本号,类似java中的继承重写。
dependency management标签:
dependencyManagement不会引入依赖
只会对继承pom有效,对于dependency方式依赖该工程的工程不会起作用
- 这个标签的作用是管理依赖的版本,当项目中使用dependencyManagement标签管理大量依赖时,并不会在项目中直接使用依赖.而是当你使用到其中的某些依赖时,不需要添加版本号.
- 这个标签用的最多的还是在父工程中实现依赖的版本管理,从而子工程不会强制使用这些依赖,只会继承依赖管理中的版本号,这样可以留给子工程选择的空间
Maven多继承:
- maven的多项目结构中,可以使用parent定义起父项目,从而从父项目中继承依赖等属性。但是美中不足,maven只能单继承,即一个项目只能使用parent标签定一个父级项目。
- 问题解决:
import scope依赖
- 注意:
依赖只能放在dependencyManagement中,如果需要被多继承的话。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.xuzimian.global.demo</groupId>
<artifactId>spring-core</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
type为pom的理解:
- dependency中type默认为jar即引入一个特定的jar包。
- 当我们需要引入很多jar包的时候会导致pom.xml过大,我们可以想到的一种解决方案是定义一个父项目,但是父项目只有一个,也有可能导致父项目的pom.xml文件过大。
这个时候我们引进来一个type为pom,意味着我们可以将所有的jar包打包成一个pom,然后我们依赖了pom,即可以下载下来所有依赖的jar包
- 注意:
①type为pom的依赖一般命名为XX-dependencies-XX。
②此外对于父项目也必须为pom,以及多继承也必须为pom。
继承操作步骤:
- 创建一个Maven工程为父工程。
①pom用在父级工程或聚合工程中。用来做jar包的版本控制。
②必须指明这个聚合工程的打包方式为pom
<1>pom格式的意思就是只生成一个pom.xml文件,而不生成其他任何jar,zip文件。
<groupId>com.maven</groupId>
<artifactId>parent</artifactId>
<version>0.1.1-SNAPSHOT</version>
<packaging>pom</packaging>
- 在子工程中声明对父工程的引用。
①<parent></parent>指定父工程
<1><relativePath></relativePath>:
以当前文件为基准的父工程pom.xml文件的相对路径,相对路径允许你选择一个不同的路径,默认值是../pom.xml
。
<parent>
<groupId>com.maven</groupId>
<artifactId>parent</artifactId>
<version>0.1.1-SNAPSHOT</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
- 将子工程的坐标与父工程中重复的内容删除
<groupId>com.maven</groupId>
- 在父工程中统一管理依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 在子工程中删除依赖的版本号
<version>4.0/version>
聚合简介:
- 作用:
①将多个工程拆分为模块后,需要手动逐个安装到仓库后依赖才能够生效。修改源码后也需要逐个手动进行 clean 操作。
②而使用了聚合之后就可以批量进行 Maven 工程的安装、清理工作。
- 配置方式:
①在一个“总的聚合工程“”中使用 modules/module 标签组合,指定模块工程的相对路径即可
<modules>
<module>../Hello</module>
<module>../HelloFriend</module>
<module>../MakeFriends</module>
</modules>
生命周期
Maven 的生命周期:
- Maven 生命周期定义了各个构建环节的执行顺序,有了这个清单,Maven 就可以自动化的执行构建命令了。
Maven 有三套相互独立的生命周期:
-
Clean Lifecycle 在进行真正的构建之前进行一些清理工作
:Clean 生命周期一共包含了三个阶段:
①pre-clean 执行一些需要在 clean 之前完成的工作
②clean 移除所有上一次构建生成的文件
③post-clean 执行一些需要在 clean 之后立刻完成的工作 -
Site Lifecycle 生成项目报告,站点,发布站点
:Site 生命周期一共包含了四个阶段:
①pre-site 执行一些需要在生成站点文档之前完成的工作
②site 生成项目的站点文档
③post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
④site-deploy 将生成的站点文档部署到特定的服务器上
<1>这里经常用到的是 site 阶段和 site-deploy 阶段,用以生成和发布 Maven 站点,这可是 Maven 相当强大的功能,Manager 比较喜欢,文档及统计数据自动生成,很好看。 -
Default Lifecycle 构建的核心部分,编译,测试,打包,安装,部署等等。
①Default 生命周期是 Maven 生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。这里只解释一些比较重要和常用的阶段:
validate
generate-sources
process-sources
generate-resources
process-resources 复制并处理资源文件,至目标目录,准备打包。
compile 编译项目的源代码。
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources 复制并处理资源文件,至目标测试目录。
test-compile 编译测试源代码。
process-test-classes
test 使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。
prepare-package
package 接受编译好的代码,打包成可发布的格式,如 JAR。
pre-integration-test
integration-test
post-integration-test
verify
install 将包安装至本地仓库,以让其它项目依赖。
deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享或部署到服务器上运行。
总结:
- 它们是相互独立的,你可以仅仅调用 clean 来清理工作目录,仅仅调用 site 来生成站点。当然你也可以直接运行 mvn clean install site 运行所有这三套生命周期。
- 每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行 mvn clean,这个clean 是 Clean 生命周期的一个阶段。有 Clean 生命周期,也有 clean 阶段。
生命周期与自动化构建:
- 运行任何一个阶段的时候,它前面的所有阶段都会被运行,例如我们运行 mvn install 的时候,代码会 被编译,测试,打包。
- 这就是 Maven 为什么能够自动执行构建过程的各个环节的原因。
- 此外,Maven 的插 件机制是完全依赖 Maven 的生命周期的,因此理解生命周期至关重要。
插件和目标:
- Maven 的核心仅仅定义了抽象的生命周期,具体的任务都是交由插件完成的。
- 每个插件都能实现多个功能,每个功能就是一个插件目标。
- Maven 的生命周期与插件目标相互绑定,以完成某个具体的构建任务。
例如:compile 就是插件 maven-compiler-plugin 的一个目标;pre-clean 是插件 maven-clean-plugin 的一个目标。
生命周期阶段 | 插件目标 | 插件 |
---|---|---|
compile | compile | maven-compile-plugin |
test-compile | test-compile | maven-compile-plugin |
- 可以将目标看作“调用插件功能的命令”。
maven之build标签概述:
- 链接:maven之build标签
- 使用maven构建的项目可以直接使用maven build完成项目的编译、测试、打包,无需额外配置。
①build标签描述了如何编译及打包项目,具体的编译和打包工作是通过其中的plugin配置来实现的。当然plugin不是必须的,即使不添加默认也会引入以下插件:
- 存在如下两种
<build>
:
①全局配置(project build)
:针对整个项目的所有情况都有效
②配置(profile build)
:`针对不同的profile配置
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
…
<!– "Project Build" contains more elements than just the BaseBuild set –>
<build>…</build>
<profiles>
<profile>
<!– "Profile Build" contains a subset of "Project Build"s elements –>
<build>…</build>
</profile>
</profiles>
基本元素:
①defaultGoal:执行build任务时,如果没有指定目标,将使用的默认值。
<1> 如上配置:在命令行中执行mvn,则相当于执行mvn install
②directory:build目标文件的存放目录,默认在${basedir}/target目录
③finalName:build目标文件的名称,默认情况为${artifactId}-${version}
④filter:定义*.properties文件,包含一个properties列表,该列表会应用到支持filter的resources中。
也就是说定义在filter的文件中的name=value键值对,会在build时代替${name}
值应用到resources中。maven的默认filter文件夹为${basedir}/src/main/filters
。
<build>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
<finalName>${artifactId}-${version}</finalName>
<filters>
<filter>filters/filter1.properties</filter>
</filters>
...
</build>
plugins标签
: 用于指定使用的插件
①GAV:指定插件的标准坐标
②extensions:是否加载plugin的extensions,默认为false
③inherited:true/false,这个plugin是否应用到该pom的孩子pom,默认为true。(继承)
④configuration:配置该plugin期望得到的properties
⑤dependencies:作为plugin的依赖
⑥executions:plugin可以有多个目标
,每一个目标都可以有一个分开的配置,可以将一个plugin绑定到不同的阶段,假如绑定antrun:run目标到verify阶段。
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.0