Maven 构建生命周期
什么是构建生命周期
构建生命周期是定义明确的阶段序列,它定义了目标的执行顺序。 这里的阶段代表生命周期中的一个阶段。 例如,典型的 Maven 构建生命周期由以下阶段序列组成。
阶段 | 处理 | 描述 |
---|---|---|
prepare-resources | 资源复制 | 在此阶段可以自定义资源复制。 |
validate | 验证信息 | 验证项目是否正确以及所有必要信息是否可用。 |
compile | 编译 | 源代码编译在此阶段完成。 |
Test | 测试 | 测试适合测试框架的编译源代码。 |
package | 打包 | 此阶段创建 POM.xml 中打包中提到的 JAR/WAR 包。 |
install | 安装 | 此阶段将软件包安装在本地/远程 maven 存储库中。 |
Deploy | 部署 | 将最终包复制到远程仓库。 |
注册目标总是有前阶段和后阶段,它们必须在特定阶段之前或之后运行。
当 Maven 开始构建项目时,它会逐步执行定义的阶段序列并执行在每个阶段注册的目标。
Maven 具有以下三个标准生命周期
- clean
- default(或者 build)
- site
目标代表有助于项目建设和管理的特定任务。 它可能绑定到零个或多个构建阶段。 未绑定到任何构建阶段的目标可以通过直接调用在构建生命周期之外执行。
执行顺序取决于调用目标和构建阶段的顺序。 例如,考虑下面的命令。 clean 和 package 参数是构建阶段,而 dependency:copy-dependencies
是目标。
$ mvn clean dependency:copy-dependencies package
这里首先会执行 clean 阶段,然后是 dependency:copy-dependencies 目标,最后会执行 package 阶段。
clean 生命周期
Maven clean 生命周期处理与从输出目录中删除临时文件相关的所有内容,包括生成的源文件、编译的类和以前的 JAR 文件等。
当我们执行 mvn post-clean
命令时,Maven 会调用由以下阶段组成的 clean 生命周期。
- pre-clean - 在实际 clean 之前执行的一些操作
- clean - 删除之前构建生成的所有文件
- post-clean - 执行完成 clean 之后所需执行的一些操作
Maven clean 目标 (clean:clean) 绑定到 clean 生命周期 中的 clean 阶段。 它的 clean:cleangoal 通过删除构建目录来删除构建的输出。 因此,当 mvn clean
命令执行时,Maven 会删除构建目录。
我们可以通过上述 clean 生命周期的任何阶段的目标来自定义此行为。
在以下示例中,我们将 maven-antrun-plugin:run 目标附加到 pre-clean、clean 和 post-clean 阶段。 这将允许我们回显 clean生命周期阶段的文本消息。
pom.xml
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.projectgroup</groupId> <artifactId>project</artifactId> <version>1.0</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.1</version> <executions> <execution> <id>id.pre-clean</id> <phase>pre-clean</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>pre-clean phase</echo> </tasks> </configuration> </execution> <execution> <id>id.clean</id> <phase>clean</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>clean phase</echo> </tasks> </configuration> </execution> <execution> <id>id.post-clean</id> <phase>post-clean</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>post-clean phase</echo> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
现在打开命令控制台,转到包含 pom.xml 的文件夹并执行以下 mvn 命令。
$ mvn post-clean
Maven 将开始处理和显示 clean生命周期的所有阶段。
可以尝试调整 mvn clean
命令,该命令将显示 pre-clean 和 clean。 post-clean 阶段不会执行任何操作。
Default (或者 Build) 生命周期
这是 Maven 的主要生命周期,用于构建应用程序。 它有以下21个阶段。
序号 | 生命周期阶段 | 描述 |
---|---|---|
1 | validate | 验证项目是否正确以及所有必要的信息是否可用于完成构建过程。 |
2 | initialize | 初始化构建状态,例如设置属性。 |
3 | generate-sources | 生成要包含在编译阶段的任何源代码。 |
4 | process-sources | 处理源代码,例如过滤任何值。 |
5 | generate-resources | 生成要包含在包中的资源。 |
6 | process-resources | 将资源复制并处理到目标目录中,为打包阶段做好准备。 |
7 | compile | 编译项目的源代码。 |
8 | process-classes | 对编译生成的文件进行后处理,例如对 Java 类进行字节码增强/优化。 |
9 | generate-test-sources | 生成要包含在编译阶段的任何测试源代码。 |
10 | process-test-sources | 处理测试源代码,例如过滤任何值。 |
11 | test-compile | 处理测试源代码,例如过滤任何值。 |
12 | process-test-classes | 处理从测试代码文件编译生成的文件。 |
13 | test | 使用合适的单元测试框架(Junit 就是其中之一)运行测试。 |
14 | prepare-package | 在实际打包之前,执行任何的必要的操作为打包做准备。 |
15 | package | 获取已编译的代码并将其打包成可分发的格式,例如 JAR、WAR 或 EAR 文件。 |
16 | pre-integration-test | 在执行集成测试之前执行所需的操作。 例如,设置所需的环境。 |
17 | integration-test | 如有必要,处理包并将其部署到可以运行集成测试的环境中。 |
18 | post-integration-test | 执行集成测试后执行所需的操作。 例如,清理环境。 |
19 | verify | 运行任何检查以验证打的包是否有效并符合质量标准。 |
20 | install | 将包安装到本地仓库中,可以作为本地其他项目的依赖。 |
21 | deploy | 将最终的项目包复制到远程仓库中与其他开发者和项目共享。 |
有一些与 Maven 生命周期相关的重要概念需要说明:
当一个阶段通过 Maven 命令调用时,例如 mvn compile,只有该阶段之前以及包括该阶段在内的所有阶段会被执行。
不同的 maven 目标将根据打包的类型(JAR / WAR / EAR),被绑定到不同的 Maven 生命周期阶段。
在下面的例子中,我们将 maven-antrun-plugin:run 目标添加到 Build 生命周期的一部分阶段中。这样我们可以显示生命周期的文本信息。
我们已经更新了pom.xml 文件。
pom.xml
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.projectgroup</groupId> <artifactId>project</artifactId> <version>1.0</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.1</version> <executions> <execution> <id>id.validate</id> <phase>validate</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>validate phase</echo> </tasks> </configuration> </execution> <execution> <id>id.compile</id> <phase>compile</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>compile phase</echo> </tasks> </configuration> </execution> <execution> <id>id.test</id> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>test phase</echo> </tasks> </configuration> </execution> <execution> <id>id.package</id> <phase>package</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>package phase</echo> </tasks> </configuration> </execution> <execution> <id>id.deploy</id> <phase>deploy</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>deploy phase</echo> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
现在打开命令控制台,跳转到 pom.xml 所在目录,并执行以下 mvn 命令。
$ mvn compile
Maven 将会开始处理并显示直到编译阶段的构建生命周期的各个阶段。
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.companyname.projectgroup:project >----------------
[INFO] Building project 1.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-antrun-plugin:1.1:run (id.validate) @ project ---
[INFO] Executing tasks
[echo] validate phase
[INFO] Executed tasks
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ project ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ project ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-antrun-plugin:1.1:run (id.compile) @ project ---
[INFO] Executing tasks
[echo] compile phase
[INFO] Executed tasks
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.743 s
[INFO] Finished at: 2022-03-01T17:47:50+08:00
[INFO] ------------------------------------------------------------------------
命令行调用
在开发环境中,使用下面的命令去构建、安装工程到本地仓库
$ mvn install
这个命令在执行 install 阶段前,按顺序执行了 default 生命周期的阶段 (validate,compile,package,等等),我们只需要调用最后一个阶段,如这里是 install。
在构建环境中,使用下面的调用来纯净地构建和部署项目到共享仓库中
$ mvn clean deploy
这行命令也可以用于多模块的情况下,即包含多个子项目的项目,Maven 会在每一个子项目执行 clean 命令,然后再执行 deploy 命令。
Site 生命周期
Maven Site 插件一般用来创建新的报告文档、部署站点等。
- pre-site:执行一些需要在生成站点文档之前完成的工作
- site:生成项目的站点文档
- post-site: 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备
- site-deploy:将生成的站点文档部署到特定的服务器上
这里经常用到的是site阶段和site-deploy阶段,用以生成和发布Maven站点,这可是Maven相当强大的功能,Manager比较喜欢,文档及统计数据自动生成,很好看。 在下面的例子中,我们将 maven-antrun-plugin:run 目标添加到 Site 生命周期的所有阶段中。这样我们可以显示生命周期的所有文本信息。
我们已经更新了目录下的 pom.xml 文件。
pom.xml
<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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.companyname.projectgroup</groupId> <artifactId>project</artifactId> <version>1.0</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-site-plugin</artifactId> <version>3.7</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-project-info-reports-plugin</artifactId> <version>2.9</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.1</version> <executions> <execution> <id>id.pre-site</id> <phase>pre-site</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>pre-site phase</echo> </tasks> </configuration> </execution> <execution> <id>id.site</id> <phase>site</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>site phase</echo> </tasks> </configuration> </execution> <execution> <id>id.post-site</id> <phase>post-site</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>post-site phase</echo> </tasks> </configuration> </execution> <execution> <id>id.site-deploy</id> <phase>site-deploy</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>site-deploy phase</echo> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
现在打开命令控制台,跳转到 pom.xml 所在目录,并执行以下 mvn 命令。
$ mvn site
Maven 将会开始处理并显示直到 site 阶段的 site 生命周期的各个阶段。
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.companyname.projectgroup:project >----------------
[INFO] Building project 1.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-antrun-plugin:1.1:run (id.pre-site) @ project ---
[INFO] Executing tasks
[echo] pre-site phase
[INFO] Executed tasks
[INFO]
[INFO] --- maven-site-plugin:3.7:site (default-site) @ project ---
[WARNING] Input file encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[WARNING] No project URL defined - decoration links will not be relativized!
[INFO] Rendering site with org.apache.maven.skins:maven-default-skin:jar:1.2 skin.
[INFO]
[INFO] --- maven-antrun-plugin:1.1:run (id.site) @ project ---
[INFO] Executing tasks
[echo] site phase
[INFO] Executed tasks
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.994 s
[INFO] Finished at: 2022-03-01T18:01:24+08:00
[INFO] ------------------------------------------------------------------------