Maven 的生命周期详解

发布于:2024-06-29 ⋅ 阅读:(19) ⋅ 点赞:(0)

Maven 是目前最流行的项目管理和构建工具之一,广泛应用于 Java 开发项目中。它通过一系列约定和配置,极大地简化了项目的构建、依赖管理和生命周期管理。其中,Maven 的生命周期是其核心概念之一,贯穿了项目从构建、测试、打包到部署的整个过程。理解和掌握 Maven 的生命周期,不仅能够提高构建效率,还能帮助开发者更好地控制项目的各个阶段。

本文将全面解析 Maven 的生命周期,详细介绍每个生命周期阶段及其执行规则。通过本文的学习,读者将能够深入理解 Maven 的生命周期机制,从而更好地应用于实际项目中。


文章目录


1、Maven 生命周期

1.1、Maven 生命周期介绍

在 Maven 出现之前,项目构建的生命周期已经存在,开发人员每天都在进行项目的清理、编译、测试和部署。然而,由于缺乏统一的规范,不同公司甚至不同项目之间的构建方式各不相同。

Maven 从大量项目和构建工具中汲取经验和反思,总结出了一套高度完美且易于扩展的生命周期。这一生命周期将项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有构建过程进行了抽象和统一。

需要注意的是,Maven 生命周期本身是抽象的,不能完成任何实际工作。这些实际工作(如源代码编译)是通过调用 Maven 插件中的插件目标(plugin goal)来完成的。我们可以将 Maven 生命周期理解成一个抽象父类,将插件理解成其子类,而插件目标则是子类中重写的方法。

通过这种方式,Maven 实现了构建过程的标准化和模块化,使得开发人员可以更轻松地管理和维护项目,提高了构建过程的可重复性和一致性。

1.2、Maven 的三套生命周期

Maven 的生命周期并非只有一套,而是有三套,并且这三套生命周期之间是相互独立的。每套生命周期包含许多不同的阶段,这些阶段是有顺序的,某些阶段必须在前一个阶段完成后才能进行。Maven 的三套生命周期分别为:clean(清理)、default(默认)和 site(站点)。

Clean 生命周期主要用于项目的清理工作。它包含以下几个阶段:

  • pre-clean:执行清理之前的工作。
  • clean:执行实际的清理工作,通常是删除项目的构建输出目录。
  • post-clean:执行清理之后的工作。

例如,当用户调用 mvn clean 命令时,clean 生命周期的所有阶段都会依次执行,当前项目的 target 目录会被清空。

Default 生命周期是 Maven 最核心的生命周期,包含了项目构建的完整流程。它包括以下主要阶段:

  • validate:验证项目是否正确且所有必要信息是否可用。
  • compile:编译项目的源代码。
  • test:使用适当的单元测试框架测试已编译的代码。
  • package:将编译后的代码打包成可分发的格式(如 JAR 文件)。
  • verify:运行任何检查以验证包是否有效且符合质量标准。
  • install:将包安装到本地仓库,以供本地其他项目使用。
  • deploy:将最终的包复制到远程仓库,以共享给其他开发人员和项目。

Site 生命周期用于生成项目的站点文档。它包含以下几个阶段:

  • pre-site:执行生成站点文档之前的工作。
  • site:生成项目的站点文档。
  • post-site:执行生成站点文档之后的工作。
  • site-deploy:将生成的站点文档发布到特定的服务器上。
1.3、Maven 生命周期执行规则

每套生命周期包含一系列的构建阶段(phase),这些阶段是有顺序的,且后面的阶段依赖于前面的阶段。用户与 Maven 最直接的交互方式就是调用这些生命周期阶段。

以 clean 生命周期为例,它包含 pre-clean、clean 以及 post-clean 三个阶段。当用户调用 pre-clean 阶段时,则只有 pre-clean 阶段执行;当用户调用 clean 阶段时,pre-clean 和 clean 阶段都会执行;而当用户调用 post-clean 阶段时,pre-clean、clean 以及 post-clean 三个阶段都会依次执行。

需要强调的是,这三套生命周期(clean、default、site)本身是相互独立的。用户可以只调用 clean 生命周期的某个阶段,也可以只调用 default 生命周期的某个阶段,而不会对其他生命周期造成任何影响。当然,用户也可以同时调用两套生命周期的某个阶段。

通过将阶段名传递给 mvn 命令,就可以调用构建阶段。例如:

mvn clean

这个命令调用的是 clean 生命周期的 clean 阶段,会清空当前项目的 target 目录。

这种设计使得 Maven 的构建过程既灵活又有序,用户可以根据需要精细地控制构建过程中的各个阶段,确保项目的构建流程高效且符合预期。


2、Maven 的三套生命周期之 clean

clean 生命周期专门用于清理项目构建过程中生成的临时文件和目录。这个生命周期包含三个阶段:pre-cleancleanpost-clean

2.1、clean 生命周期阶段 pre-clean

pre-cleanclean 生命周期的第一个阶段。在此阶段,Maven 会执行任何绑定到 pre-clean 阶段的插件目标(goal)。这通常用于在清理项目构建之前执行一些清理前的准备工作,例如关闭数据库连接、停止服务器等。

PS:在 Maven 的默认行为中,pre-clean 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-antrun-plugin(Maven 官方插件)插件的 run 目标来自定义行为。

2.2、clean 生命周期阶段 clean*

cleanclean 生命周期的核心阶段。在此阶段,Maven 会清理项目的构建输出,例如 target/ 目录(默认情况下)。这是通过执行 maven-clean-plugin(Maven 官方插件)的 clean 目标来实现的。

2.3、clean 生命周期阶段 post-clean

post-cleanclean 生命周期的最后一个阶段。在此阶段,Maven 会执行任何绑定到 post-clean 阶段的插件目标。这通常用于在清理项目构建之后执行一些清理后的工作,例如删除临时文件、日志等。

PS:在 Maven 的默认行为中,post-clean 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-antrun-plugin(Maven 官方插件)插件的 run 目标来自定义行为。


3、Maven 的三套生命周期之 default

default 生命周期是 Maven 的核心生命周期,主要用于处理项目的构建和发布。这个生命周期包含一系列阶段,涵盖了项目从初始化到部署的整个过程。

3.1、default 生命周期阶段 validate

validate 阶段是 default 生命周期中的第一个阶段。在此阶段,Maven 会验证项目是否正确,以及所有必要的信息是否可用。这通常包括检查 POM 文件(pom.xml)中的信息是否完整和有效,例如,确认依赖项、插件和属性都已正确声明。

PS:在 Maven 的默认行为中,validate 阶段没有绑定任何插件目标,用户可以使用 maven-enforcer-plugin(Maven 官方插件)插件的 enforce 目标来自定义行为。

PS:在 Maven 的生命周期中,validate 阶段虽然没有绑定具体的插件目标,但 Maven 也会在此阶段检查 POM 文件的基本结构和配置的正确性。这些检查是由 Maven 核心机制自动执行的。

3.2、default 生命周期阶段 initialize

initialize 阶段是 default 生命周期中紧随 validate 阶段之后的阶段。这个阶段通常用于在构建开始之前设置或初始化一些值,例如,从配置文件或环境变量中读取值,并设置到 Maven 的属性中。

PS:在 Maven 的默认行为中,initialize 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-antrun-plugin(Maven 官方插件)插件的 run 目标来自定义行为。

3.3、default 生命周期阶段 generate-sources

generate-sources 阶段用于生成所有需要包含在编译过程中的源代码文件。这些生成的源代码文件随后会被 Maven 编译器(如 maven-compiler-plugin)编译。

这个阶段通常用于自动生成源代码,比如使用代码生成工具(如 JAXB、Annotation Processors 等)从配置文件、数据库模式或其他元数据生成 Java 类。

PS:在 Maven 的默认行为中,generate-sources 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 build-helper-maven-plugin(非官方插件,由 Codehaus Mojo 提供)插件的 add-source 目标来自定义行为。

3.4、default 生命周期阶段 process-sources

process-sources 阶段用于处理项目主源代码。这通常包括对源代码文件进行过滤(如替换占位符),但它也可以执行其他类型的源代码处理任务。

在 Maven 中,这个阶段默认不会执行任何操作,除非有插件被绑定到这个阶段。

PS:在 Maven 的默认行为中,process-sources 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 formatter-maven-plugin(非官方插件,由 Codehaus Mojo 提供)插件的 format 目标来自定义行为。

3.5、default 生命周期阶段 generate-resources

generate-resources 阶段用于生成项目主资源文件。这些资源文件(如配置文件、国际化文件等)将被包含在最终的打包文件中。

generate-sources 阶段类似,这个阶段通常用于自动生成资源文件。例如,你可以使用模板引擎(如 FreeMarker、Velocity 等)从模板生成配置文件。

PS:在 Maven 的默认行为中,generate-resources 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 build-helper-maven-plugin(非官方插件,由 Codehaus Mojo 提供)插件的 add-source 目标来自定义行为。

3.6、default 生命周期阶段 process-resources*

process-resources 阶段用于复制并处理项目主资源文件到目标目录,准备打包。这通常包括对资源文件进行过滤(如替换占位符),以及将资源文件复制到正确的目录中。

Maven 使用 maven-resources-plugin (Maven 官方插件)的 resources 目标来处理资源文件,该插件默认绑定到 process-resources 阶段。在构建过程中,Maven 会查找 src/main/resources 目录下的所有资源文件,并将它们复制到 target/classes 目录中(对于主资源)或 target/test-classes 目录中(对于测试资源)。同时,Maven 还会根据配置对资源文件进行过滤处理。

3.7、default 生命周期阶段 compile*

compile 阶段是 Maven 生命周期中的一个核心阶段,用于编译项目的主源代码。这个阶段通常使用 Java 编译器(如 javac)将 Java 源代码文件(.java)编译成字节码文件(.class)。

Maven 使用 maven-compiler-plugin(Maven 官方插件)的 compile 目标来执行编译任务,该插件默认绑定到 compile 阶段。你可以在 pom.xml 文件中配置 maven-compiler-plugin 的属性,以指定 Java 编译器选项(如源代码和目标字节码的版本、是否启用调试信息等)。

当 Maven 执行到 compile 阶段时,它会检查项目的主源代码目录(默认为 src/main/java),并编译其中的所有 Java 文件。编译后的字节码文件将被放置在项目的构建输出目录(默认为 target/classes)中。

3.8、default 生命周期阶段 process-classes

process-classes 阶段是 Maven 生命周期中 compile 阶段之后的一个阶段,用于处理编译后的字节码文件(.class),如执行字节码分析、优化或转换等任务。

PS:在 Maven 的默认行为中,process-classes 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-shade-plugin(非官方插件,由 Codehaus Mojo 提供)插件的 shade 目标来自定义行为。

3.9、default 生命周期阶段 generate-test-sources

generate-test-sources 阶段用于生成所有需要包含在测试编译过程中的测试源代码文件。这些生成的测试源代码文件随后会被 Maven 编译器(如 maven-compiler-plugin)编译,用于执行测试。

这个阶段通常用于自动生成测试源代码,比如使用代码生成工具从数据库模式或其他元数据生成测试数据或测试类。

PS:在 Maven 的默认行为中,generate-test-sources 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 build-helper-maven-plugin(非官方插件,由 Codehaus Mojo 提供)插件的 add-test-source 目标来自定义行为。

3.10、default 生命周期阶段 process-test-sources

process-test-sources 阶段用于处理项目测试源代码。这通常包括对测试源代码文件进行过滤(如替换占位符),但它也可以执行其他类型的测试源代码处理任务。

PS:在 Maven 的默认行为中,process-test-sources 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 formatter-maven-plugin(非官方插件,由 Codehaus Mojo 提供)插件的 format 目标来自定义行为。

3.11、default 生命周期阶段 generate-test-resources

generate-test-resources 阶段用于生成项目测试资源文件。这些测试资源文件(如测试配置文件、测试数据等)将被包含在测试构建过程中。

generate-test-sources 阶段类似,这个阶段通常用于自动生成测试资源文件。例如,你可以使用模板引擎从模板生成测试配置文件。

PS:在 Maven 的默认行为中,generate-test-resources 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 build-helper-maven-plugin(非官方插件,由 Codehaus Mojo 提供)插件的 add-test-source 目标来自定义行为

3.12、default 生命周期阶段 process-test-resources

process-test-resources 阶段用于复制并处理项目测试资源文件到目标目录,准备测试构建。这通常包括对测试资源文件进行过滤(如替换占位符),以及将测试资源文件复制到正确的目录中。

Maven 使用 maven-resources-plugin 来处理测试资源文件,该插件默认绑定到 process-test-resources 阶段。在构建过程中,Maven 会查找 src/test/resources 目录下的所有测试资源文件,并将它们复制到 target/test-classes 目录中。同时,Maven 还会根据配置对测试资源文件进行过滤处理。

PS:在 Maven 的默认行为中,process-test-resources 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-resources-plugin(Maven 官方插件)插件的 testResources 目标来自定义行为

3.13、default 生命周期阶段 test-compile*

test-compile 阶段是 Maven 生命周期中的一个阶段,用于编译项目的测试源代码。在这个阶段,Maven 会查找 src/test/java 目录下的所有测试源代码文件(通常是 .java 文件),并使用 Java 编译器(由 maven-compiler-plugin(Maven 官方插件)插件 testCompile 目标提供)将它们编译成字节码文件(.class)。这些编译后的测试类文件会被放置在项目的构建输出目录(默认为 target/test-classes)中,以便在后续阶段中执行测试。

3.14、default 生命周期阶段 process-test-classes

process-test-classes 阶段是 Maven 生命周期中 test-compile 阶段之后的一个阶段,用于处理编译后的测试类文件。然而,与 process-classes 阶段类似,Maven 的默认实现并不在 process-test-classes 阶段执行任何特定的操作。这个阶段主要是为了允许用户通过绑定插件来执行自定义的构建任务,以处理编译后的测试类文件。

PS:在 Maven 的默认行为中,process-test-classes 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-shade-plugin(非官方插件,由 Codehaus Mojo 提供)插件的 shade 目标来自定义行为

3.15、default 生命周期阶段 test*

test 阶段是 Maven 生命周期中用于执行测试的一个关键阶段。在这个阶段,Maven 会使用 maven-surefire-plugin 插件的 test 目标(或其他测试插件)来运行 target/test-classes 目录下编译后的测试类。这些测试类通常包含了一系列用于验证项目功能的测试用例。

测试的执行结果会被收集并报告给 Maven,以便你可以了解哪些测试成功执行,哪些测试失败。如果所有测试都成功执行,则 Maven 会继续执行后续的构建阶段;如果有测试失败,则 Maven 会停止构建过程,并输出相应的错误信息。

3.16、default 生命周期阶段 prepare-package

prepare-package 阶段是用于准备打包步骤,例如生成附加的文件或执行其他准备工作。

PS:prepare-package 阶段并不是 Maven 官方默认生命周期的一个标准阶段。

PS:在 Maven 的默认行为中,prepare-package 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-antrun-plugin(Maven 官方插件)插件的 run 目标来自定义行为

3.17、default 生命周期阶段 package*

package 阶段是 Maven 生命周期中的一个核心阶段,用于将编译后的代码、资源、配置文件等打包成可发布的格式,如 JAR、WAR 或 EAR 文件。这个阶段的目标是将编译和测试通过的代码打包成可交付的构建产物。

Maven 使用特定的打包插件来执行 package 阶段的任务,例如 maven-jar-plugin(Maven 官方插件)的 jar 目标 用于打包 JAR 文件,maven-war-plugin(Maven 官方插件)的 war 目标用于打包 WAR 文件等。这些插件会根据项目的 pom.xml 文件中的配置来生成相应的构建产物。

package 阶段之前,Maven 会确保所有必要的构建阶段都已成功执行,包括 compiletest-compiletest 等。只有在这些阶段都成功完成后,Maven 才会进入 package 阶段,并开始打包项目。

一旦 package 阶段成功完成,Maven 会将构建产物放置在项目的 target 目录下,并准备进行后续的部署或分发操作。

3.18、default 生命周期阶段 pre-integration-test

pre-integration-test 阶段是集成测试之前的一个阶段,主要用于执行在集成测试开始之前需要完成的准备工作。这个阶段可能包括设置测试环境、准备测试数据等任务。

PS:在 Maven 的默认行为中,pre-integration-test 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-antrun-plugin(Maven 官方插件)插件的 run 目标来自定义行为

3.19、default 生命周期阶段 integration-test

integration-test 阶段是 Maven 生命周期中用于执行集成测试的阶段。集成测试通常用于验证项目中的不同组件是否能够协同工作,以及项目与外部系统(如数据库、消息队列等)的集成是否正确。

在这个阶段,Maven 会运行项目中定义的集成测试用例,以验证系统的整体功能。集成测试用例通常比单元测试更为复杂,因为它们需要模拟或访问外部系统。

PS:在 Maven 的默认行为中,integration-test 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-failsafe-plugin(Maven 官方插件)插件的 integration-test 目标来自定义行为

3.20、default 生命周期阶段 post-integration-test

post-integration-test 阶段是集成测试之后的一个阶段,主要用于执行在集成测试完成后需要完成的一些清理工作。这可能包括清除测试环境、恢复系统状态等任务

PS:在 Maven 的默认行为中,post-integration-test 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-antrun-plugin(Maven 官方插件)插件的 run 目标来自定义行为

3.21、default 生命周期阶段 verify*

verify阶段是在所有集成测试通过后执行的,用于对项目进行额外的检查以确保质量。这个阶段可以执行一些自定义的验证逻辑,比如检查代码覆盖率、检查生成的文档是否完整等。

如果 verify 阶段成功完成,那么表示项目的质量已经通过了验证,可以继续进行后续的部署和发布操作。

PS:在 Maven 的默认行为中,verify 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-verifier-plugin(非官方插件,由 Codehaus Mojo 提供)插件的 verify 目标来自定义行为

3.22、default 生命周期阶段 install*

install 阶段将项目的构建结果安装到本地 Maven 仓库中,以供其他项目使用。这意味着,一旦某个项目完成了install 阶段,它的构建产物(如JAR、WAR文件等)就会被复制到本地 Maven 仓库的相应目录中。其他 Maven 项目可以通过依赖配置,直接从本地 Maven 仓库中获取并使用这些构建产物,从而避免了重复构建相同的依赖项。

install 阶段通常是在本地开发环境中执行的,用于将项目构建产物安装到本地仓库,以便在本地进行其他项目的依赖引用和测试。

在这个阶段中使用将 maven-install-plugin(Maven 官方插件)的 install 目标来实现目标。

3.23、default 生命周期阶段 deploy*

deploy 阶段将项目的构建结果复制到远程仓库,以供其他开发人员或团队使用。这是项目发布到外部世界的最后一步。

deploy 阶段,Maven 会将项目的构建产物(如 JAR、WAR 文件等)上传到指定的远程 Maven 仓库中。这样,其他开发人员或团队就可以通过远程 Maven 仓库来获取和使用这些构建产物。

deploy 阶段通常是在持续集成/持续部署(CI/CD)环境中执行的,用于将项目构建产物发布到公共或私有的远程 Maven 仓库中,以便其他人员或团队可以访问和使用。

在这个阶段中使用将 maven-deploy-plugin(Maven 官方插件)的 deploy 目标来实现目标。


4、Maven 的三套生命周期之 site

site 生命周期用于生成和部署项目的站点文档,使得项目文档的生成和发布变得简便高效。这个生命周期包含四个阶段:pre-sitesitepost-sitesite-deploy

4.1、site 生命周期阶段 pre-site

pre-site阶段是site生命周期的开始阶段,它在生成站点文档之前执行。这个阶段通常用于执行任何必要的预处理步骤,例如准备环境或检查某些条件。

PS:在 Maven 的默认行为中,pre-site 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-antrun-plugin(Maven 官方插件)插件的 run 目标来自定义行为。

4.2、site 生命周期阶段 site

site 阶段是 site 生命周期的核心部分。在此阶段,Maven 使用maven-site-plugin (Maven 官方插件)插件的 site 目标(或其他类似的插件)来生成项目的站点文档。这些文档可能包括项目信息、报告、API 文档等。

4.3、site 生命周期阶段 post-site

post-site阶段在site阶段之后执行,用于执行任何必要的后处理步骤。在此阶段可以执行自定义任务,例如复制文件、修改生成的站点内容等。

PS:在 Maven 的默认行为中,post-site 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-antrun-plugin(Maven 官方插件)插件的 run 目标来自定义行为。

4.4、site 生命周期阶段 site-deploy

site-deploy阶段是site生命周期的最后阶段。在此阶段,Maven将生成的站点文档部署到某个位置,以便其他人可以访问。这通常是通过将站点内容发布到Web服务器或文件共享服务来实现的。

PS:在 Maven 的默认行为中,post-site 阶段没有绑定任何插件目标,因此并不执行任何操作,用户可以使用 maven-site-plugin(Maven 官方插件)插件的 deploy 目标来自定义行为。