execution绑定的phase决定插件goal在maven生命周期中何时触发;常用且安全的phase包括generate-sources、compile、package、verify,需匹配实际执行的mvn命令所涉生命周期阶段。

mvn 命令执行时,execution 绑定的 phase 到底起什么作用
它决定了插件目标(goal)在 Maven 生命周期中**何时被触发**。不是写上就运行,也不是所有 phase 都能随便绑——绑错 phase,插件可能根本不执行,或者执行时机错乱,比如想在编译后生成代码,却绑到了 initialize,那肯定啥也等不到。
哪些 phase 值最常用、最安全
优先选标准生命周期里的稳定节点,避免自定义或冷门 phase。Maven 3+ 中推荐以下几个:
-
generate-sources:适合代码生成类插件(如protobuf-maven-plugin),确保生成的源码能被后续compile正确识别 -
compile:适合需要干预编译过程的逻辑(如字节码增强),但注意此时源码已解析,不能改 .java 文件内容 -
package:适合打包前的校验、资源过滤、jar 合并等操作,绝大多数构建后处理放这里最稳妥 -
verify:适合运行集成测试、静态检查(如spotbugs),它在package之后、install之前,失败不影响本地安装
绑定 phase 后却没执行?常见原因
不是配置写了就生效,Maven 会按实际命令决定走哪段生命周期。例如:
- 只运行
mvn compile,那么只有绑定在compile及其之前 phase(如process-classes)的 execution 才会触发;绑定在package的完全静默 - 插件未声明
<goals></goals>,或<goal></goal>拼错(比如写成exec而非exec@java),phase再对也没用 - 多个
<execution></execution>共享同一id,后声明的会覆盖前一个,导致你以为绑了两个,其实只剩一个 - 父 POM 或 BOM 中已有同插件同
id的 execution,子模块未显式设<inherited>false</inherited>就会被继承并可能冲突
phase 和 goal 的关系别搞混
phase 是生命周期坐标,goal 是插件能力点。一个插件可以有多个 goal(如 maven-surefire-plugin:2.22.2:test),每个 execution 只能指定一个 goal,但可绑定到任意合法 phase。常见误操作:
- 把
phase当成插件版本控制字段——它不参与依赖解析,也不影响插件加载 - 以为绑到
clean就能删掉 target 目录下插件生成的文件——clean是独立生命周期,除非你显式运行mvn clean,否则不会触发 - 在
site生命周期里绑定编译类插件(如compiler),结果 build 失败:因为site不包含compile阶段,相关产物根本不存在
真正关键的是:你跑的那条 mvn xxx 命令,对应哪个生命周期,里面有哪些 phase 会被走到——其他都只是纸面配置。










