生命周期和插件也是 Maven 的核心概念,我们的日常 Maven 命令行输入都对应生命周期,Maven 的生命周期是抽象的概念,其实际操作都由插件来完成,生命周期和插件协同工作。
生命周期
Maven 的生命周期就是为了对所有的构建过程进行抽象和统一。这个生命周期包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有构建步骤。也就是说,几乎所有项目的构建,都能映射到这样一个生命周期上。
三套生命周期详解
Maven 拥有三套相互独立的生命周期,它们分别是 clean、default 和 site。
- clean:该生命周期的目的是清理项目;
- default:此生命周期目的是构件项目;
- site:为了建立项目站点。
每个生命周期都包含一些阶段(phase),这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段,用户和 Maven 最直接的交互方式就是调用这些生命周期阶段。
较之于生命周期阶段的前后依赖关系,三套生命周期本身是相互独立的,用户可以仅仅调用 clean 生命周期的某个阶段,或者仅仅调用 default 生命周期的某个阶段,而不会对其他生命周期产生任何影响。
clean 生命周期的目的是清理项目,它包含三个阶段:
- pre-clean:执行一些清理前需要完成的工作;
- clean:清理上一次构件的文件;
- post-clean:执行一些清理后需要完成的工作。
default 生命周期定义了真正构建时所需要执行的所有步骤,它是所有生命周期中最核心的部分,其包含如下 23 个阶段:
- validate:检查工程配置是否正确,完成构建过程的所有必要信息是否能够获取到;
- initialize:初始化构建状态,例如设置属性;
- generate-sources:生成编译阶段需要包含的任何源码文件;
- process-sources:处理项目主资源文件。一般来说,是对 src/main/resources 目录的内容进行变量替换等工作后,复制到项目输出到主 classpath 目录中;
- generate-resources:生成工程包中需要包含的资源文件;
- process-resources:拷贝和处理资源文件到目的目录中,为打包阶段做准备;
- compile:编译项目的主源码。一般来说,是对 src/main/java 目录下的 Java 文件至项目输出到主 classpath 目录中;
- process-classes:处理编译生成的文件,例如 Java Class 字节码的加强和优化;
- generate-test-sources:生成编译阶段需要包含的任何测试源代码;
- process-test-sources:处理项目测试资源文件。一般来说,是对 src/test/resources 目录的内容进行变量替换等工作后,复制到项目输出到测试 classpath 目录中;
- generate-test-resources:生成工程包中测试需要包含的资源文件;
- process-test-resources:处理测试源代码,例如,过滤任何值(filter any values);
- test-compile:编译项目的测试代码。一般来说,是对 src/test/java 目录下的 Java 文件至项目输出到测试 classpath 目录中;
- process-test-classes:处理测试代码文件编译后生成的文件;
- test:使用单元测试框架运行测试,测试代码不会被打包或部署;
- prepare-package:在真正打包之前,为准备打包执行任何必要的操作;
- package:接受编译后的代码,并打包成可发布的格式,如 jar、war 或 ear 文件;
- pre-integration-test:在集成测试执行之前,执行所需的操作。例如,设置所需的环境变量;
- integration-test:处理和部署必须的工程包到集成测试能够运行的环境中;
- post-integration-test:在集成测试被执行后执行必要的操作。例如,清理环境;
- verify:运行检查操作来验证工程包是有效的,并满足质量要求;
- install:将包安装到本地 Maven 仓库,供本地其它 Maven 项目使用;
- deploy:将最终的包复制到远程仓库,供其它开发人员和其它 Maven项目使用。
site 生命周期的目的是建立和发布项目站点,Maven 能够基于 POM 所包含的信息,自动生成一个友好的站点,方便团队交流和发布项目信息。该生命周期包含如下阶段:
- pre-site:执行一些在生成项目站点之前需要完成的工作;
- site:生成站点项目文档;
- post-site:执行一些在生成项目站点之后需要完成的工作;
- site-deploy:将生成的项目站点发布到服务器上。
命令行与生命周期
从命令行执行 Maven 任务的最主要方式就是调用 Maven 的生命周期阶段。值得注意的是,各个生命周期是相互独立的,而一个生命周期的阶段是有前后依赖关系的。
下面以一些常见的 Maven 命令为例,解释其执行的生命周期阶段:
mvn clean
该命令调用 clean 生命周期的 clean 阶段。实际执行的阶段为 clean 生命周期的 pre-clean 和 clean 阶段。
mvn test
该命令调用 default 生命周期的 test 阶段。实际执行的阶段为 default 生命周期的 validate、initialize 等,直到 test 的所有阶段。这也解释了为什么在执行测试的时候,项目的代码能够自动编译。
mvn clean install
该命令调用 clean 生命周期的 clean 阶段和 default 生命周期的 install 阶段。实际执行的阶段为 clean 生命周期的 pre-clean、clean 阶段,以及 default 生命周期的从 validate 至 install 的所有阶段。该命令结合了两个生命周期,在执行真正的项目构建之前清理项目是一个很好的实践。
mvn clean deploy site-deploy
该命令调用 clean 生命周期的 clean 阶段、default 生命周期的 deploy 阶段,以及 site 生命周期的 site-deploy 阶段。实际执行的阶段为 clean 生命周期的 pre-clean、clean 阶段,default 生命周期的所有阶段,以及 site 生命周期的所有阶段。该命令结合了 Maven 所有三个生命周期,且 deploy 为 default 生命周期的最后一个阶段,site-deploy 为 site 生命周期的最后一个阶段。
Maven 插件
Maven 的核心仅仅定义了抽象的生命周期,具体的任务是交由插件完成的,插件以独立的构件形式存在,因此,Maven 核心的分发包只有不到几兆的大小,Maven 会在需要的时候下载并使用插件。
插件绑定
Maven 的生命周期与插件相互绑定,用以完成实际的构建任务。具体而言,是生命周期的阶段与插件的目标相互绑定,以完成某个具体的构建任务。
为了能让用户几乎不用任何配置就能构建 Maven 项目,Maven 在核心为一些主要的生命周期阶段绑定了很多插件的目标,当用户通过命令行调用生命周期阶段的时候,对应的插件目标就会执行相应的任务。
生命周期阶段 | 插件目标 |
---|---|
pre-clean | |
clean | maven-clean-plugin:clean |
post-clean |
生命周期阶段 | 插件目标 |
---|---|
pre-site | |
site | maven-site-plugin:site |
post-site | |
site-deploy | maven-site-plugin:deploy |
生命周期阶段 | 插件目标 | 执行任务 |
---|---|---|
process-resources | maven-resources-plugin:resources | 复制主资源文件至主输出目录 |
compile | maven-compiler-plugin:compile | 编译主代码至主输出目录 |
process-test-resources | maven-resources-plugin:testResources | 复制测试资源文件至测试输出目录 |
test-compile | maven-compiler-plugin:testCompile | 编译测试代码至测试输出目录 |
test | maven-surefire-plugin:test | 执行测试用例 |
package | maven-jar-plugin:jar | 创建项目 jar 包 |
install | maven-install-plugin:install | 将项目输出构件安装到本地仓库 |
deploy | maven-deploy-plugin:deploy | 将项目输出构件安装到远程仓库 |