乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • 第1章 介绍与核心概念

    • Maven是什么
    • 约定优于配置
  • 第2章 安装与配置

    • 安装与验证
    • settings.xml
    • 本地仓库与镜像
  • 第3章 POM与项目坐标

    • POM
    • GAV坐标
    • packaging
  • 第4章 标准目录布局

    • 标准目录布局
  • 第5章 依赖机制

    • dependencies
    • scope
    • 依赖传递
    • 依赖冲突与调解
    • exclusions
    • optional
    • dependencyManagement
  • 第6章 仓库

    • 仓库体系
    • 本地仓库
    • 远程仓库与镜像
    • 私服
  • 第7章 构建生命周期

    • 生命周期概述
    • clean 生命周期
    • default 生命周期
    • site 生命周期
    • 生命周期与插件绑定
  • 第8章 插件

    • 插件概述
    • maven-compiler-plugin
    • maven-surefire-plugin
    • maven-war-plugin
  • 第9章 继承与聚合

    • parent继承
    • 聚合
    • BOM
    • properties
  • 第10章 属性与资源过滤

    • 资源过滤
    • Profile
  • 第11章 常用命令

    • mvn compile
    • mvn test
    • mvn package
    • mvn clean
    • mvn install
    • mvn dependency:tree
  • 第12章 常见问题与最佳实践

    • 依赖冲突排查
    • 最佳实践

default 生命周期

本章承接"生命周期概述",深入讲解 default 生命周期——Maven 最核心、最常用的构建流水线。理解 validate 到 deploy 各阶段的输入输出和职责边界,是掌握 Maven 构建原理、精准排查构建失败、设计 CI/CD 流水线的关键。


核心机制

default 生命周期是项目的主构建生命周期,用于构建和分发项目。其核心阶段包括 validate → compile → test → package → verify → install → deploy。虽然生命周期中实际包含二十多个阶段,但日常开发中只需掌握上述核心阶段的含义和顺序。

default 生命周期的核心阶段

default 生命周期是 Maven 的"主流水线",负责从源代码到可部署产物的完整转化。以下是核心阶段的详细说明:

阶段职责典型输入典型输出默认绑定的插件目标
validate验证项目结构和 POM 的合法性pom.xml验证报告无默认绑定(可自定义)
compile编译主源代码src/main/java/*.javatarget/classes/*.classmaven-compiler-plugin:compile
test运行单元测试src/test/java/*Test.java + target/classes/测试报告 + target/surefire-reports/maven-surefire-plugin:test
package将编译结果打包为可分发的格式target/classes/target/*.jar 或 *.warmaven-jar-plugin:jar(JAR 项目)
verify对打包结果进行完整性检查target/*.jar验证报告无默认绑定(可自定义)
install将包安装到本地仓库target/*.jar~/.m2/repository/.../*.jarmaven-install-plugin:install
deploy将包发布到远程仓库/私服target/*.jar远程仓库中的构件maven-deploy-plugin:deploy

阶段的输入输出链

default 生命周期的阶段之间形成了清晰的数据流:

src/main/java/*.java
    ↓ [compile]
target/classes/*.class
    ↓ [test]
测试通过报告
    ↓ [package]
target/employee-system-1.0.0.jar
    ↓ [verify]
验证通过报告
    ↓ [install]
~/.m2/repository/com/feixiang/employee-system/1.0.0/employee-system-1.0.0.jar
    ↓ [deploy]
http://nexus.feixiang.tech/repository/company-releases/.../employee-system-1.0.0.jar

这个链条体现了 Maven 构建的阶段性递进:每个阶段的输出是下一个阶段的输入,构建产物从源代码逐步转化为可部署的远程构件。

阶段的累积性再强调

由于累积性,执行后面的阶段会自动触发前面的阶段:

执行的命令实际执行的阶段链
mvn compilevalidate → compile
mvn testvalidate → compile → test
mvn packagevalidate → compile → test → package
mvn installvalidate → compile → test → package → verify → install
mvn deployvalidate → compile → test → package → verify → install → deploy

生活类比:食品加工厂

想象一家将新鲜水果加工成罐头的食品厂:

  • validate = 原料验收:检查送来的水果是否新鲜、农药残留是否达标、包装标签是否完整。如果原料不合格,整批退货,后续工序不启动
  • compile = 清洗切割:把水果洗净、去皮、切块,变成"半成品"(.class 文件)。这是核心加工的第一步
  • test = 质检抽检:从切割好的半成品中抽样,检测糖分、酸度、微生物指标。如果抽检不合格,整批半成品报废
  • package = 灌装封口:把合格的半成品装入罐头瓶、抽真空、封盖,变成"成品"(JAR 包)
  • verify = 出厂检验:对成品罐头进行跌落测试、密封性测试、保质期模拟。确保送到消费者手里不会漏、不会坏
  • install = 入库分销中心:把成品罐头运到全国各大超市的仓库(本地仓库),供各地门店(其他项目)上架销售
  • deploy = 出口海外:把罐头装上远洋货轮,运到国外经销商的仓库(远程仓库/私服),进入国际市场

这个类比的关键在于:每个阶段都有明确的输入、输出和验收标准,前一阶段的输出不合格,后一阶段不会启动。这也是 Maven 构建失败时,你需要根据报错信息判断"哪个工位出了问题"的原因。


图示

上图展示了 default 生命周期的完整阶段链和数据流。每个阶段的输出(绿色/蓝色节点)成为下一个阶段的输入,形成一条从源代码到远程构件的完整流水线。


完整示例

场景

飞翔科技的 employee-system 项目完成了 1.0.0 版本的开发,CTO 大翔要求架构师白歌向团队演示 default 生命周期各阶段的实际效果,确保每个人都理解 mvn compile、mvn test、mvn package、mvn install、mvn deploy 的区别和适用场景。

操作前:项目已准备好发布

项目结构:

employee-system/
├── pom.xml
├── src/
│   ├── main/
│   │   ├── java/com/feixiang/employee/
│   │   │   ├── EmployeeService.java
│   │   │   └── EmployeeController.java
│   │   └── resources/application.properties
│   └── test/
│       └── java/com/feixiang/employee/
│           └── EmployeeServiceTest.java

pom.xml 关键配置:

<project>
    <groupId>com.feixiang</groupId>
    <artifactId>employee-system</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <distributionManagement>
        <repository>
            <id>company-releases</id>
            <url>http://nexus.feixiang.tech/repository/company-releases/</url>
        </repository>
    </distributionManagement>
</project>

操作步骤

白歌依次执行各阶段命令,展示输入输出的变化。

步骤 1:compile 阶段

mvn compile

输出:

[INFO] --- maven-compiler-plugin:3.10.1:compile (default-compile) @ employee-system ---
[INFO] Compiling 2 source files to /home/baige/employee-system/target/classes

输入:src/main/java/ 下的 2 个 .java 文件
输出:target/classes/com/feixiang/employee/ 下的 2 个 .class 文件

步骤 2:test 阶段

mvn test

输出:

[INFO] --- maven-compiler-plugin:3.10.1:testCompile (default-testCompile) @ employee-system ---
[INFO] Compiling 1 test source file to /home/baige/employee-system/target/test-classes
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ employee-system ---
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ employee-system ---

输入:src/test/java/EmployeeServiceTest.java + target/classes/(被测试的类)
输出:target/test-classes/(编译后的测试类) + target/surefire-reports/(测试报告)

注意:由于累积性,mvn test 自动先执行了 compile,所以 target/classes/ 已经存在。

步骤 3:package 阶段

mvn package

输出:

[INFO] --- maven-jar-plugin:3.3.0:jar (default-jar) @ employee-system ---
[INFO] Building jar: /home/baige/employee-system/target/employee-system-1.0.0.jar

输入:target/classes/ + src/main/resources/
输出:target/employee-system-1.0.0.jar

注意:由于累积性,mvn package 自动先执行了 compile 和 test。如果测试失败,package 阶段不会执行。

步骤 4:install 阶段

mvn install

输出:

[INFO] --- maven-install-plugin:3.1.0:install (default-install) @ employee-system ---
[INFO] Installing /home/baige/employee-system/target/employee-system-1.0.0.jar to /home/baige/.m2/repository/com/feixiang/employee-system/1.0.0/employee-system-1.0.0.jar
[INFO] Installing /home/baige/employee-system/pom.xml to /home/baige/.m2/repository/com/feixiang/employee-system/1.0.0/employee-system-1.0.0.pom

输入:target/employee-system-1.0.0.jar
输出:~/.m2/repository/com/feixiang/employee-system/1.0.0/ 下的 JAR 和 POM

步骤 5:deploy 阶段

mvn deploy

输出:

[INFO] --- maven-deploy-plugin:3.1.1:deploy (default-deploy) @ employee-system ---
[INFO] Uploading to company-releases: http://nexus.feixiang.tech/repository/company-releases/com/feixiang/employee-system/1.0.0/employee-system-1.0.0.jar
[INFO] Uploaded to company-releases: http://nexus.feixiang.tech/.../employee-system-1.0.0.jar (12 kB at 156 kB/s)

输入:target/employee-system-1.0.0.jar + pom.xml
输出:Nexus 私服 company-releases 仓库中的构件

操作结果

变化分析:

  • 小崔理解了 compile 只是"半成品",不能独立运行;package 才是"成品",可以 java -jar 执行
  • 黄俪明白了为什么联调时要先 mvn install——只有 install 到本地仓库后,她的前端项目(通过 Maven 引用了 employee-system)才能解析到最新版本
  • 李眉确认了 Jenkins 流水线的正确命令是 mvn clean deploy——deploy 会自动走完前面所有阶段,最终把产物发布到私服,供生产环境拉取
  • 大翔在项目管理工具中标记 1.0.0 版本为"已发布",因为 deploy 成功意味着构件已进入公司级仓库

易错点与常见问题

误区一:mvn compile 会执行 test

错误认知:"我执行 mvn compile,Maven 应该会顺便跑一下测试吧?毕竟编译完测一下很正常。"

纠正:mvn compile 只执行到 compile 阶段,不会触发 test。测试阶段在 compile 之后,只有显式执行 mvn test 或更后面的阶段(如 mvn package)时,测试才会运行。这个设计是有意为之——编译是高频操作(写几行代码就编译一下),测试是低频操作(通常写完一个功能再统一测试)。如果每次编译都跑测试,开发效率会大幅下降。

误区二:install 和 deploy 是一样的

错误认知:"mvn install 和 mvn deploy 都是'发布',只是名字不同。"

纠正:两者的发布目标完全不同:

命令目标仓库范围用途
mvn install本地仓库 ~/.m2/repository仅当前开发者本地跨项目引用、临时测试
mvn deploy远程仓库/私服全公司/全网正式版本发布、CI/CD 交付

install 是"本地发布",只有你自己能用;deploy 是"远程发布",团队所有人都能下载。在 CI/CD 流水线中,应该用 deploy;在本地开发时,如果另一个项目需要引用当前项目的最新代码,用 install。

误区三:跳过测试是安全的

错误认知:"赶时间的时候用 mvn package -DskipTests,反正代码我本地测过了,跳过 Maven 的测试没问题。"

纠正:-DskipTests 确实跳过了 maven-surefire-plugin 的测试执行,但测试代码仍然会被编译。更危险的是 -Dmaven.test.skip=true,它连测试代码的编译都跳过。如果测试代码里有编译错误(如引用了已删除的 API),这个参数会让错误被掩盖,直到其他开发者拉取代码后才发现。跳过测试应该是临时手段,而非常态。


小结

default 生命周期是 Maven 的"主构建流水线",由 validate、compile、test、package、verify、install、deploy 等阶段组成。每个阶段有明确的输入输出,形成从源代码到远程构件的完整数据流。阶段的累积性意味着执行后面的阶段会自动触发前面的所有阶段。理解各阶段的职责边界,是选择正确 Maven 命令(compile vs package vs install vs deploy)的基础。

本章与全局的关系:本章深入讲解了"如何构建和发布项目"。下一章"site 生命周期"将讲解 Maven 的文档生成能力——如何自动生成项目报告站点。

上一页
clean 生命周期
下一页
site 生命周期