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

    • 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章 常见问题与最佳实践

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

clean 生命周期

本章承接"生命周期概述",聚焦 clean 生命周期。理解 pre-clean、clean、post-clean 三个阶段的分工,是掌握构建环境清理、避免旧产物干扰新构建的基础。


核心机制

clean 生命周期用于清理项目,包含三个阶段:pre-clean、clean、post-clean。说明:

最常用的阶段是 clean,它会删除 target 目录以及任何其他被配置为需要删除的目录或文件。需要特别注意的是,target 是默认被删除的目录,但你可以通过配置让 clean 阶段删除其他目录。

clean 生命周期的三个阶段

阶段名称作用默认绑定的插件目标
pre-clean清理前阶段执行一些需要在正式清理之前完成的准备工作无默认绑定
clean清理阶段删除构建输出目录(默认 target/)maven-clean-plugin:clean
post-clean清理后阶段执行一些需要在清理之后完成的收尾工作无默认绑定

mvn clean 的作用

当你执行 mvn clean 时,Maven 会依次执行 pre-clean → clean → post-clean。由于 pre-clean 和 post-clean 默认没有绑定任何插件目标,实际有可见效果的是 clean 阶段。

clean 阶段绑定的 maven-clean-plugin:clean 目标默认删除以下内容:

  • 项目根目录下的 target/ 目录(包含编译后的 .class 文件、打包的 JAR/WAR、测试报告等)
  • 任何在 pom.xml 中通过 <filesets> 额外配置的文件或目录

自定义清理范围

如果默认删除 target/ 不够,你可以在 pom.xml 中扩展 clean 插件的配置:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-clean-plugin</artifactId>
            <version>3.2.0</version>
            <configuration>
                <filesets>
                    <fileset>
                        <directory>logs</directory>
                        <includes>
                            <include>*.log</include>
                        </includes>
                    </fileset>
                    <fileset>
                        <directory>temp</directory>
                    </fileset>
                </filesets>
            </configuration>
        </plugin>
    </plugins>
</build>

上述配置会让 mvn clean 在删除 target/ 的同时,也删除 logs/ 目录下的所有 .log 文件和整个 temp/ 目录。

生活类比:餐厅打烊后的清台

想象一家餐厅(项目)每天营业结束后的清台流程:

  • pre-clean = 清点贵重餐具:服务员先检查有没有客人落下的钱包、手机,确保不会误扔重要物品
  • clean = 清理桌面和地面:把剩菜倒掉、擦桌子、扫地——这是清台的核心动作,对应删除 target/ 目录
  • post-clean = 消毒和锁门:清理完成后,用消毒液擦拭,检查煤气阀门,最后锁门

这个类比的关键在于:clean 是核心动作,但 pre-clean 和 post-clean 提供了"钩子",让你可以在清理前后插入自定义逻辑。比如 pre-clean 阶段可以备份 target/ 里的测试报告,post-clean 阶段可以发送"构建环境已清理"的通知。


图示

上图展示了 clean 生命周期的阶段流程。clean 阶段是唯一的"有默认行为"的阶段,前后两个阶段是"空钩子",供开发者插入自定义逻辑。


完整示例

场景

飞翔科技的 employee-system 项目连续进行了多轮迭代,后端工程师小崔发现最近几次构建出现了诡异的行为:修改了代码但运行时还是旧逻辑、测试报告里混入了上次的失败记录。架构师白歌诊断后认为,是 target/ 目录里的旧产物没有被清理,建议小崔养成"每次正式构建前执行 mvn clean"的习惯,并向团队演示 clean 前后的目录变化。

操作前:target 目录被旧产物污染

小崔连续执行了多次构建命令,但没有清理过 target/。当前目录状态:

employee-system/
├── pom.xml
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/feixiang/employee/
│   │   │       ├── EmployeeService.java      # 最新代码
│   │   │       └── OldLogic.java             # 已删除的源文件
│   │   └── resources/
│   └── test/
│       └── java/
└── target/
    ├── classes/
    │   └── com/feixiang/employee/
    │       ├── EmployeeService.class         # 最新编译结果
    │       └── OldLogic.class                # ❌ 旧产物!源文件已删但 .class 还在
    ├── test-classes/
    ├── surefire-reports/                     # 上次的测试报告
    │   ├── com.feixiang.employee.EmployeeServiceTest.txt
    │   └── com.feixiang.employee.OldTest.txt # ❌ 旧测试类已删但报告还在
    └── employee-system-1.0.0.jar             # 包含 OldLogic.class 的脏包

问题:

  • OldLogic.java 已在上一轮重构中删除,但 target/classes/OldLogic.class 仍然存在
  • mvn package 打出的 JAR 包含了 OldLogic.class,导致生产环境出现已废弃的逻辑
  • 旧测试报告 OldTest.txt 干扰了测试结果的判断

操作步骤

步骤 1:执行 clean

小崔在项目根目录执行:

mvn clean

控制台输出:

[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------< com.feixiang:employee-system >------------------
[INFO] Building employee-system 1.0.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:3.2.0:clean (default-clean) @ employee-system ---
[INFO] Deleting /home/xiaocui/employee-system/target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

步骤 2:验证清理结果

执行 ls target/(Windows 用 dir target):

ls target/

输出:

ls: cannot access 'target/': No such file or directory

target/ 目录已被完全删除。

步骤 3:重新完整构建

小崔执行组合命令:

mvn clean package

构建成功后,检查新的 target/ 目录:

target/
├── classes/
│   └── com/feixiang/employee/
│       └── EmployeeService.class         # ✅ 只有当前存在的源文件对应的 .class
├── test-classes/
│   └── com/feixiang/employee/
│       └── EmployeeServiceTest.class
├── surefire-reports/
│   └── com.feixiang.employee.EmployeeServiceTest.txt  # ✅ 只有当前测试的报告
└── employee-system-1.0.0.jar             # ✅ 干净的 JAR,不含旧逻辑

操作结果

变化分析:

  • OldLogic.class 和 OldTest.txt 等旧产物被彻底清除,不再污染新的构建产物
  • 打包的 JAR 只包含当前代码库中存在的类,消除了"已删代码幽灵般重现"的风险
  • 小崔在团队内推广了"mvn clean package 组合命令"的最佳实践,前端黄俪和运维李眉也理解了为什么 CI/CD 流水线里总是先 clean 再构建
  • 白歌在 pom.xml 中增加了对 logs/ 目录的清理配置,确保每次构建前日志文件也被重置

易错点与常见问题

误区一:clean 只是删除 target 目录

错误认知:"mvn clean 不就是 rm -rf target 吗?我自己手动删也一样。"

纠正:手动删除 target/ 确实能达到大部分效果,但 mvn clean 的价值在于:

  • 可扩展性:通过 pom.xml 配置,可以一并清理 logs/、temp/、generated-sources/ 等其他目录
  • 可移植性:Windows 上手动删是 rmdir /s /q target,Linux 上是 rm -rf target,而 mvn clean 在任何平台都一样
  • 可集成性:pre-clean 和 post-clean 阶段可以绑定自定义插件,实现"清理前自动备份""清理后发送通知"等自动化流程

误区二:clean 会删除本地仓库

错误认知:"mvn clean 会不会把我 ~/.m2/repository 里的依赖也删掉?那下次构建不是要重新下载?"

纠正:mvn clean 只删除项目目录下的 target/,绝不会触碰本地仓库 ~/.m2/repository。本地仓库里的依赖是跨项目共享的缓存,删除它们属于"自残"行为。如果你确实需要清理本地仓库(如某个依赖损坏),必须手动删除对应 GAV 路径下的目录,或者使用 mvn dependency:purge-local-repository 插件。

误区三:clean 生命周期会自动执行

错误认知:"我执行 mvn package,Maven 应该会先自动 clean 吧?不然旧产物不会干扰吗?"

纠正:mvn package 不会自动执行 clean。clean 和 default 是两个独立的生命周期,没有内置的触发关系。如果你需要"先清理再打包",必须显式执行 mvn clean package。很多新手在 IDE 里点"Rebuild Project"时,IDE 会隐式执行 clean,导致他们误以为 mvn package 也会自动清理。在 CI/CD 流水线中,忘记加 clean 是构建产物污染的常见原因。


小结

clean 生命周期是 Maven 三套生命周期中最简单、最直观的一套,由 pre-clean、clean、post-clean 三个阶段组成。clean 阶段通过 maven-clean-plugin 默认删除 target/ 目录,并支持通过 pom.xml 扩展清理范围。它的核心价值在于确保每次构建从零开始的环境纯净性,避免旧编译产物、旧测试报告、旧打包文件对新构建的干扰。

本章与全局的关系:本章讲解了"如何清理构建环境"。下一章"default 生命周期"将深入讲解 Maven 最核心的构建流水线——从 validate 到 deploy 的完整阶段链。

上一页
生命周期概述
下一页
default 生命周期