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
属性使用