Maven 的插件机制允许在同一个 plugin 声明中配置多个 execution,分别绑定到不同的生命周期阶段或赋予不同 id。但在实际执行时,Maven 并不会因为你在命令行敲了一个看似相关的命令,就自动把该插件下所有 execution 全部运行。理解这一行为是解决问题的前提。

为什么默认不会运行所有 execution
Maven 的生命周期由一系列阶段(phase)组成,例如 compile、package、verify 等。当你执行如 mvn package 时,Maven 只会触发从起始阶段到 package 之间的所有阶段,并执行那些绑定在这些阶段上的 execution。如果一个 execution 绑定在 deploy 阶段,那么 package 命令自然不会触发它。
此外,很多插件目标(goal)如果在命令行直接调用,例如 mvn sonar:sonar,Maven 会查找该插件中 id 为 default-cli 的 execution 配置;如果不存在,就使用默认参数,而忽略你在 pom 中写的其他带自定义 id 的 execution。这就造成了“明明配了多个 execution,为什么只跑了一个”的困惑。
通过 default-cli 一次性应用全部配置
如果你希望无论通过命令行直接调用插件目标,还是通过生命周期触发,都能复用同一份参数,可以把公共配置抽出来,并显式增加一个 id 为 default-cli 的 execution。这样命令行直接调用时也会采用这些配置。
不过需要注意,default-cli 只是解决了“参数复用”,并不能把多个不同 id 的 execution 合并执行。下面示例展示如何为 maven-antrun-plugin 配置 default-cli:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>default-cli</id>
<configuration>
<target>
<echo>运行默认命令行配置</echo>
</target>
</configuration>
</execution>
<execution>
<id>attach-build-info</id>
<phase>prepare-package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo>绑定到 prepare-package 阶段</echo>
</target>
</configuration>
</execution>
</executions>
</plugin>
上述配置中,attach-build-info 会在 prepare-package 阶段自动执行,而当你运行 mvn antrun:run 时,会采用 default-cli 中的配置。两者互不干扰,但命令行方式不会触发 attach-build-info。
用 profile 绑定统一阶段来批量触发
若你的真实诉求是“把同一个插件的好几个 execution 一次性全跑”,最稳妥的做法是让这些 execution 都绑定到同一个生命周期阶段,然后通过一条 Maven 命令触发该阶段。如果某些 execution 原本分散在不同阶段,可以借助 profile 重新绑定。
以下示例通过 profile 把两个不同任务的 execution 都绑定到 process-resources 阶段,这样执行 mvn process-resources -Pall-exec 就能一次性跑完:
<profiles>
<profile>
<id>all-exec</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>task-a</id>
<phase>process-resources</phase>
<goals><goal>run</goal></goals>
<configuration>
<target><echo>任务A</echo></target>
</configuration>
</execution>
<execution>
<id>task-b</id>
<phase>process-resources</phase>
<goals><goal>run</goal></goals>
<configuration>
<target><echo>任务B</echo></target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
这种方式的优势是清晰可控:你不需要记住多个命令,只要激活对应 profile 并跑到指定阶段,所有相关 execution 都会按顺序执行。缺点是若 execution 之间有严格阶段依赖,强行放在同阶段可能破坏原有构建逻辑,需要评估合理性。
直接命令行显式调用多个目标
当插件目标彼此独立且不需要生命周期上下文时,也可以在命令行中连续写出多个插件目标,从而显式触发。例如:
mvn org.apache.maven.plugins:maven-antrun-plugin:run@task-a org.apache.maven.plugins:maven-antrun-plugin:run@task-b
上面写法中的 @task-a 表示指定执行 id 为 task-a 的 execution。该方式适合临时调试,不需要改 pom,但命令冗长,且要求 execution 已经存在于默认生命周期绑定或可被直接寻址。
总体来看,若追求可维护的构建脚本,推荐用 profile 统一阶段绑定;若只是本地验证,可用命令行显式调用。理解 Maven 的 execution 匹配规则,才能避免配置明明写了却不被执行的尴尬。
Mavenplugin_executionlifecycle修改时间:2026-08-08 08:18:32