5.2 Maven 基础
前置知识:为什么需要包管理
预计时间:15 分钟
阅读方式:先读 POM 与生命周期,联网构建留到真实项目
完成标志:能读 POM、运行生命周期并解释 Maven 的锁定边界
Java 依赖不只需要下载,还要进入正确的编译、测试和运行 classpath。Maven 用 POM 描述项目,并用生命周期把这些步骤串起来。
POM 与构件坐标
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>example.workshop</groupId>
<artifactId>hello-maven</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version>
</plugin>
</plugins>
</build>
</project>这是一份放在项目根目录的 pom.xml,以 Maven 3.6.3+、JDK 17 为示例环境。显式固定编译插件,避免老版本 Maven 的默认插件忽略 maven.compiler.release;release=17 同时约束语法、字节码和可用的 Java SE API。此 POM 还没有源码或测试,所以一次成功构建只能证明空项目配置可用。参见 Compiler Plugin 的 release 说明。
groupId:artifactId:version 是构件坐标。命名空间是否唯一取决于发布者治理,不能靠字符串自动保证。
生命周期阶段
./mvnw clean verify # 有 Wrapper 时优先
mvn clean verify # 无 Wrapper 时使用本机 Maven
mvn dependency:tree
mvn help:effective-pom调用 verify 会依次经过 validate、compile、test、package 等前置阶段。install 还会把构件写入本地 Maven 仓库,供本机其他构建解析;它不负责把应用安装进操作系统。
Wrapper 把 Maven 版本写进项目。首次使用可能下载 Maven,Windows 使用 mvnw.cmd。Wrapper 固定构建工具版本,但不自动锁定全部依赖和插件。
scope 决定 classpath
| scope | 主代码编译 | 主代码运行 | 测试 |
|---|---|---|---|
compile | 是 | 是 | 是 |
provided | 是 | 由运行环境提供 | 是 |
runtime | 否 | 是 | 是 |
test | 否 | 否 | 是 |
dependencyManagement 管理版本和默认属性,dependencies 才声明项目实际使用的依赖。BOM 通常以 type=pom、scope=import 导入前者。
Maven 没有默认完整 lock
POM 中的明确版本和 BOM 能减少漂移,但传递依赖、插件、父 POM、仓库内容、快照、JDK 与构建参数仍会影响结果。可重复构建需要:
- 提交 Maven Wrapper 并控制 JDK/工具链;
- 明确直接依赖、插件和仓库策略;
- 避免可变快照进入发布构建;
- 验证下载制品,并在 CI 做干净构建。
requirements.txt 不是 Maven lock,pom.xml 也不等价于 npm 的整棵 package-lock.json。
Git 边界
提交 pom.xml、Wrapper 文件、源码和测试。忽略 target/。.idea/ 与 .vscode/ 是否提交由团队决定,不能一概全部忽略。