Maven生命周期
前言
Github:https://github.com/HealerJean
1、Maven 构建(build)生命周期的几个阶段
一个典型的
Maven构建(build)生命周期是由以下几个阶段的序列组成的:

| 阶段 | 处理 | 描述 |
|---|---|---|
验证 validate |
验证项目 | 验证项目是否正确且所有必须信息是可用的 |
编译 compile |
执行编译 | 源代码编译在此阶段完成 |
测试 Test |
测试 | 使用适当的单元测试框架(例如JUnit)运行测试。 |
包装 package |
打包 | 创建JAR/WAR包如在 pom.xml 中定义提及的包 |
检查 verify |
检查 | 对集成测试的结果进行检查,以保证质量达标 |
安装 install |
安装 | 安装打包的项目到本地仓库,以供其他项目使用 |
部署 deploy |
部署 | 拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程 |
2、Maven 有以下三个标准的生命周期
为了完成
default生命周期,这些阶段(包括其他未在上面罗列的生命周期阶段)将被按顺序地执行。
Maven有以下三个标准的生命周期:⬤
clean:项目清理的处理⬤
default或build):项目构建+部署的处理⬤
site:项目站点文档创建的处理
2.1、Clean 生命周期
当我们执行
mvn post-clean命令时,Maven调用clean生命周期,它包含以下阶段:
⬤ pre-clean:执行一些需要在clean之前完成的工作
⬤ clean:移除所有上一次构建生成的文件
⬤ post-clean:执行一些需要在clean之后立刻完成的工作
2.1.1、mvn clean
mvn clean中的clean就是上面的clean,在一个生命周期中,运行某个阶段的时候,它之前的所有阶段都会被运行,也就是说,如果执行mvn clean将运行以下两个生命周期阶段:
pre-clean, clean
2.1.2、mvn post-clean
如果我们运行
mvn post-clean,则运行以下三个生命周期阶段:
pre-clean, clean, post-clean
2.2、Default (Build) 生命周期
这是
Maven的主要生命周期,被用于构建应用,包括下面的 23 个阶段:
| validate(校验) | 校验项目是否正确并且所有必要的信息可以完成项目的构建过程。 |
|---|---|
| initialize(初始化) | 初始化构建状态,比如设置属性值。 |
| generate-sources(生成源代码) | 生成包含在编译阶段中的任何源代码。 |
| process-sources(处理源代码) | 处理源代码,比如说,过滤任意值。 |
| generate-resources(生成资源文件) | 生成将会包含在项目包中的资源文件。 |
| process-resources (处理资源文件) | 复制和处理资源到目标目录,为打包阶段最好准备。 |
compile(编译) |
编译项目的源代码。 |
| process-classes(处理类文件) | 处理编译生成的文件,比如说对Java class文件做字节码改善优化。 |
| generate-test-sources(生成测试源代码) | 生成包含在编译阶段中的任何测试源代码。 |
| process-test-sources(处理测试源代码) | 处理测试源代码,比如说,过滤任意值。 |
| generate-test-resources(生成测试资源文件) | 为测试创建资源文件。 |
| process-test-resources(处理测试资源文件) | 复制和处理测试资源到目标目录。 |
| test-compile(编译测试源码) | 编译测试源代码到测试目标目录. |
| process-test-classes(处理测试类文件) | 处理测试源码编译生成的文件。 |
| test(测试) | 使用合适的单元测试框架运行测试(Juint是其中之一)。 |
| prepare-package(准备打包) | 在实际打包之前,执行任何的必要的操作为打包做准备。 |
| package(打包) | 将编译后的代码打包成可分发格式的文件,比如JAR、WAR或者EAR文件。 |
| pre-integration-test(集成测试前) | 在执行集成测试前进行必要的动作。比如说,搭建需要的环境。 |
| integration-test(集成测试) | 处理和部署项目到可以运行集成测试环境中。 |
| post-integration-test(集成测试后) | 在执行集成测试完成后进行必要的动作。比如说,清理集成测试环境。 |
| verify (验证) | 运行任意的检查来验证项目包有效且达到质量标准。 |
| install(安装) | 安装项目包到本地仓库,这样项目包可以用作其他本地项目的依赖。 |
| deploy(部署) | 将最终的项目包复制到远程仓库中与其他开发者和项目共享。 |
2.2.1、mvn compile
只有该阶段之前以及包括该阶段在内的所有阶段会被执行。
2.2.2、mvn install
这个命令在执行
install阶段前,按顺序执行了 default 生命周期的阶段 (validate,compile,package,等等),我们只需要调用最后一个阶段,如这里是install。
mvn install
2.2.3、mvn clean deploy
在构建环境中,使用下面的调用来纯净地构建和部署项目到共享仓库中
这行命令也可以用于多模块的情况下,即包含多个子项目的项目,
Maven会在每一个子项目执行clean命令,然后再执行deploy命令。
mvn clean deploy
2.3、Site 生命周期
Maven Site插件一般用来创建新的报告文档、部署站点等。 使用maven的site插件生成项目相关信息的网站并且可以在浏览器中查看项目的站点,以下的文章是最基本的操作,可以添加其他的属性生成更加完善的站点文档。
⬤ pre-site:执行一些需要在生成站点文档之前完成的工作
⬤ site:生成项目的站点文档
⬤ post-site: 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
⬤ site-deploy:将生成的站点文档部署到特定的服务器上
这里经常用到的是site 阶段和 site-deploy阶段,用以生成和发布Maven站点,这可是Maven相当强大的功能,Manager比较喜欢,文档及统计数据自动生成,很好看。 在下面的例子中,我们将 maven-antrun-plugin:run 目标添加到 Site 生命周期的所有阶段中。这样我们可以显示生命周期的所有文本信息。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.3</version>
<configuration>
<locales>zh_CN</locales>
</configuration>
</plugin>

3、scope
Maven的生命周期存在编译、测试、运行这些过程,那么显然有些依赖只用于测试,⬤ 比如
junit;有些依赖编译用不到,只有运行的时候才能用到⬤ 比如
mysql的驱动包在编译期就用不到(编译期用的是JDBC接口),而是在运行时用到的;⬤ 还有些依赖,编译期要用到,而运行期不需要提供,因为有些容器已经提供了,比如servlet-api在tomcat中已经提供了,我们只需要的是编译期提供而已。
总结说来,在
POM 4中,<dependency>中还引入了<scope>,它主要管理依赖的部署。大致有compile、provided、runtime、test、system等几个。
3.1、compile (编译范围)
默认就是
compile,该依赖需要参与当前项目的编译、测试、运行、打包
3.2、runntime (运行时范围)
runntime表示被依赖项目无需参与项目的编译,不过后期的测试和运行周期需要其参与。与compile相比,跳过编译而已.比如,你可能在编译的时候只需要
JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。
3.3、 test (测试范围)
test范围依赖 在一般的编译和运行时都不需要,它们只有在测试编译和测试运行阶段可用。比如
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
3.4、provided (已提供范围)
provided表明该依赖已经提供,故只在未提供时才被使用,应用场景是你定义了一个
Servlet,此刻得需要Servlet-api.jar才能编译成功,但是当你达成war包时,你并不想将Servlet-api.jar包进去,因为Tomcat等容器会提供该依赖会由系统组件提供,不需手动添加,只存在编译、运行、测试阶段,打包是不用包进去,打包阶段做了
exclude动作provided意味着打包的时候可以不用包进去,别的设施(Web Container)会提供。
3.5、system (系统范围)
被依赖项不会从
maven仓库下载,而是从本地系统指定路径下寻找,需要systemPath属性
system范围依赖与provided类似,但是你必须显式的提供一个对于本地系统中JAR文件的路径,这么做是为了允许基于本地对象编译,而这些对象是系统类库的一部分。这样的构件应该是一直可用的,Maven也不会在仓库中去寻找它从参与度来说,与
provided相同,不过被依赖项不会从maven仓库抓,而是从本地文件系统拿,一定需要配合systemPath属性使用


