构建生命周期
Maven 的构建生命周期是其核心概念之一。理解生命周期对于正确使用 Maven 至关重要。本章将详细介绍 Maven 的三套生命周期及其阶段。
什么是生命周期?
Maven 的生命周期是对所有项目构建过程的抽象和统一。它定义了项目构建的各个阶段以及阶段之间的顺序关系。Maven 内置了三套相互独立的生命周期,每套生命周期包含多个阶段。
生命周期的核心思想是:开发者只需要告诉 Maven 要做什么,而不需要关心怎么做。Maven 会按照预定的顺序执行各个阶段,每个阶段的具体工作由插件完成。
三套生命周期
Maven 定义了三套相互独立的生命周期:
| 生命周期 | 作用 | 主要阶段 |
|---|---|---|
| clean | 清理项目 | pre-clean, clean, post-clean |
| default | 构建项目(核心) | validate, compile, test, package, install, deploy |
| site | 生成项目站点 | pre-site, site, post-site, site-deploy |
这三套生命周期相互独立,可以单独调用,也可以一起调用。例如执行 mvn clean package 会先执行 clean 生命周期的 clean 阶段,然后执行 default 生命周期的 package 阶段。
Clean 生命周期
Clean 生命周期用于清理项目,包含三个阶段:
阶段说明
| 阶段 | 说明 |
|---|---|
| pre-clean | 执行清理前的准备工作 |
| clean | 删除构建目录(target)中的所有内容 |
| post-clean | 执行清理后的收尾工作 |
执行示例
# 执行 clean 阶段
mvn clean
# 执行整个 clean 生命周期
mvn pre-clean clean post-clean
执行 mvn clean 会依次执行 pre-clean 和 clean 阶段。
Default 生命周期
Default 生命周期是 Maven 的核心生命周期,包含了项目构建的主要阶段。
阶段说明
Default 生命周期包含以下主要阶段(按执行顺序):
| 阶段 | 说明 |
|---|---|
| validate | 验证项目是否正确,所有必要信息是否可用 |
| initialize | 初始化构建状态,如创建目录 |
| 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、war 等) |
| pre-integration-test | 集成测试前的准备工作 |
| integration-test | 执行集成测试 |
| post-integration-test | 集成测试后的清理工作 |
| verify | 验证包的有效性和质量 |
| install | 将包安装到本地仓库 |
| deploy | 将包部署到远程仓库 |
阶段依赖关系
Maven 生命周期的关键特性是:执行某个阶段时,会自动执行该阶段之前的所有阶段。
例如执行 mvn package 时,Maven 会依次执行:
validate -> initialize -> generate-sources -> ... -> compile -> test -> package
常用命令
# 编译源代码
mvn compile
# 运行测试
mvn test
# 打包(包含编译和测试)
mvn package
# 安装到本地仓库
mvn install
# 部署到远程仓库
mvn deploy
# 清理并打包
mvn clean package
# 跳过测试打包
mvn package -DskipTests
# 跳过测试编译和执行
mvn package -Dmaven.test.skip=true
Site 生命周期
Site 生命周期用于生成项目站点文档。
阶段说明
| 阶段 | 说明 |
|---|---|
| pre-site | 生成站点前的准备工作 |
| site | 生成项目站点文档 |
| post-site | 生成站点后的收尾工作 |
| site-deploy | 将站点部署到服务器 |
执行示例
# 生成站点
mvn site
# 生成并部署站点
mvn site-deploy
阶段与插件目标
Maven 的生命周期阶段本身不执行任何工作,实际的工作由插件目标完成。
插件目标绑定
每个阶段可以绑定一个或多个插件目标。当执行某个阶段时,Maven 会执行绑定到该阶段的所有插件目标。
例如,compile 阶段默认绑定了 maven-compiler-plugin 的 compile 目标:
compile 阶段 -> maven-compiler-plugin:compile 目标
内置绑定
Maven 为 Default 生命周期的主要阶段提供了默认的插件绑定:
| 阶段 | 插件目标 | 说明 |
|---|---|---|
| process-resources | resources:resources | 复制资源文件 |
| compile | compiler:compile | 编译源代码 |
| process-test-resources | resources:testResources | 复制测试资源 |
| test-compile | compiler:testCompile | 编译测试代码 |
| test | surefire:test | 运行单元测试 |
| package | jar:jar / war:war | 打包 |
| install | install:install | 安装到本地仓库 |
| deploy | deploy:deploy | 部署到远程仓库 |
自定义绑定
可以在 pom.xml 中将插件目标绑定到特定阶段:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
这个配置将 maven-source-plugin 的 jar-no-fork 目标绑定到 package 阶段,在打包时自动生成源码包。
命令行执行
执行单个阶段
mvn compile
mvn test
mvn package
执行多个阶段
# 执行 clean 和 package
mvn clean package
# 执行 clean、test 和 install
mvn clean test install
执行完整生命周期
# 从 validate 开始执行到 deploy
mvn deploy
# 清理后完整构建
mvn clean deploy
指定项目
# 指定模块构建
mvn clean install -pl module-name
# 同时构建依赖模块
mvn clean install -pl module-name -am
# 同时构建被依赖模块
mvn clean install -pl module-name -amd
常用构建命令
基础构建命令
# 清理项目
mvn clean
# 编译项目
mvn compile
# 运行测试
mvn test
# 打包项目
mvn package
# 安装到本地仓库
mvn install
# 部署到远程仓库
mvn deploy
组合命令
# 清理并打包
mvn clean package
# 清理并安装
mvn clean install
# 清理并部署
mvn clean deploy
# 完整构建流程
mvn clean install site
跳过测试
# 跳过测试执行(仍会编译测试代码)
mvn package -DskipTests
# 完全跳过测试(不编译也不执行)
mvn package -Dmaven.test.skip=true
指定配置文件
# 激活指定 Profile
mvn package -Pdev
# 激活多个 Profile
mvn package -Pdev,test
# 指定 settings.xml
mvn package -s /path/to/settings.xml
# 指定 pom.xml
mvn package -f /path/to/pom.xml
调试和诊断
# 显示详细错误信息
mvn package -e
# 显示调试信息
mvn package -X
# 离线模式(只使用本地仓库)
mvn package -o
# 更新快照依赖
mvn package -U
生命周期与项目打包类型
不同的打包类型有不同的生命周期阶段绑定:
JAR 项目默认绑定
| 阶段 | 插件目标 |
|---|---|
| process-resources | resources:resources |
| compile | compiler:compile |
| process-test-resources | resources:testResources |
| test-compile | compiler:testCompile |
| test | surefire:test |
| package | jar:jar |
| install | install:install |
| deploy | deploy:deploy |
WAR 项目默认绑定
| 阶段 | 插件目标 |
|---|---|
| process-resources | resources:resources |
| compile | compiler:compile |
| process-test-resources | resources:testResources |
| test-compile | compiler:testCompile |
| test | surefire:test |
| package | war:war |
| install | install:install |
| deploy | deploy:deploy |
POM 项目
打包类型为 pom 的项目通常没有编译和打包的绑定,主要用于:
- 父项目
- 聚合项目
生命周期扩展
自定义生命周期阶段绑定
通过配置插件,可以将插件目标绑定到任意阶段:
<build>
<plugins>
<!-- 在 generate-sources 阶段生成代码 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.2</version>
<executions>
<execution>
<id>generate-mybatis</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
执行多个目标
一个阶段可以绑定多个插件目标,按声明顺序执行:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
小结
本章我们学习了:
- Maven 生命周期的概念和作用
- 三套生命周期及其阶段
- 阶段之间的依赖关系
- 阶段与插件目标的绑定关系
- 常用的构建命令
- 如何自定义生命周期阶段绑定
在下一章中,我们将深入学习 Maven 插件的使用。