认识2个单词:goal/target —————— 为什么Maven是 "goal" 而不是 "target"?
先看一个maven构建的错误信息:Failed to execute goal org.apache.maven.plugins:maven-install-plugin:2.5.2:install
你有没有留意过,为什么 Maven 的基本执行单元叫 ”goal“ 而不是 "target" ?
这是一个很好的问题!
📊 构建工具术语对比
| 概念 | Maven | Ant | Gradle |
|---|---|---|---|
| 基本构建单元 | Goal(目标) | Target(目标) | Task(任务) |
| 构建文件 | pom.xml |
build.xml |
build.gradle |
| 执行语法 | mvn <goal> |
ant <target> |
gradle <task> |
| 生命周期 | 有明确的构建生命周期 | 无固定生命周期 | 基于任务依赖 |
| 依赖管理 | 内置(中央仓库) | 需要手动配置 | 灵活,兼容 Maven/Ivy |
🎯 为什么 Maven 使用 "Goal"?
1. 哲学理念不同
<!-- Maven: 声明式配置,关注"做什么" -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<goals>
<goal>install</goal> <!-- 这里就是 goal -->
</goals>
</plugin>
<!-- Ant: 命令式脚本,关注"怎么做" -->
<target name="install" depends="compile,test">
<copy file="${dist}/myapp.jar" todir="${install.dir}"/>
</target>
- Maven 的 Goal:更抽象,代表要达成的目标
- Ant 的 Target:更具体,代表要执行的步骤
2. Maven 的三层结构
graph TD
A[Maven 生命周期 Lifecycle] --> B[阶段 Phase]
B --> C[目标 Goal]
D[clean 生命周期] --> E[pre-clean]
E --> F[clean]
F --> G[post-clean]
H[default 生命周期] --> I[validate]
I --> J[compile]
J --> K[test]
K --> L[package]
L --> M[verify]
M --> N[install]
N --> O[deploy]
P[site 生命周期] --> Q[site]
Q --> R[deploy-site]
S[插件 Plugin] --> T[目标 Goal]
N -.->|由 install:install goal 实现| S
Maven 的结构:
- 生命周期 (Lifecycle):如
clean、default、site - 阶段 (Phase):如
compile、test、package、install - 目标 (Goal):插件提供的具体执行单元
以下面的错误信息为例:
Failed to execute goal org.apache.maven.plugins:maven-install-plugin:2.5.2:install (default-install)
on project sby-component-biz:
Failed to install artifact
com.serviceshare:sby-component-biz:jar:1.0.202602-SNAPSHOT:
/maven/LocalStore/com/serviceshare/sby-component-biz/1.0.202602-SNAPSHOT/sby-component-biz-1.0.202602-SNAPSHOT.jar
(Permission denied)
这里的结构是:
- 插件:
maven-install-plugin - 目标:
install - 完整 Goal 引用:
org.apache.maven.plugins:maven-install-plugin:2.5.2:install
这个错误发生在:
- 插件:
maven-install-plugin - 目标:
installgoal - 原因:权限问题导致无法写入本地仓库
对应的 Maven 命令可能是:
mvn install # 或 mvn deploy
🔧 实际执行示例
Maven Goal 的执行
# 执行单个 goal
mvn clean:clean # clean 插件的 clean goal
mvn compiler:compile # compiler 插件的 compile goal
mvn surefire:test # surefire 插件的 test goal
# 执行生命周期阶段(会触发多个 goals)
mvn compile # 触发 compile 阶段的所有 goals
mvn install # 触发直到 install 阶段的所有 goals
# Jenkins 中常见的 Maven 配置
mvn clean deploy # 先执行 clean 生命周期,再执行到 deploy 阶段
与 Ant Target 的对比
<!-- Ant 的 build.xml -->
<project name="MyProject" default="dist" basedir=".">
<target name="init">
<!-- 初始化 -->
</target>
<target name="compile" depends="init">
<!-- 编译 -->
</target>
<target name="dist" depends="compile">
<!-- 打包 -->
</target>
</project>
执行:
ant dist # 执行 dist target 及其依赖的 targets
📈 历史背景
| 时期 | 工具 | 术语 | 特点 |
|---|---|---|---|
| 2000年 | Ant | Target | 基于 XML 的构建脚本,类似 Makefile |
| 2004年 | Maven | Goal | 约定优于配置,声明式构建 |
| 2012年 | Gradle | Task | 基于 Groovy/DSL,灵活且强大 |
Maven 选择 "Goal" 的原因:
- 更抽象:强调要达到的目的而不是具体步骤
- 约定优于配置:标准的生命周期和 goals
- 插件架构:goals 由插件提供,可扩展
💎 总结
设计哲学:
- Maven Goal:强调"要完成什么"(声明式)
- Ant Target:强调"要执行什么"(命令式)
简单记忆:
- 看到
goal→ 想到 Maven - 看到
target→ 想到 Ant - 看到
task→ 想到 Gradle
当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!--buguge
本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/buguge/p/19675240
浙公网安备 33010602011771号