源本科技 | 码上会

Maven 概述

2026/03/17
33
0

引言

在现代 Java 生态系统中,项目构建工具是开发流程的基石。MavenGradle 是目前最主流的两大构建工具,它们都旨在解决项目依赖管理、构建自动化和标准化问题,但设计理念各有侧重。

Maven:约定优于配置

Maven 是一个开源的项目管理工具,专为 Java 项目设计。它的核心理念是 “约定优于配置”。通过定义一套标准的项目对象模型(Project Object Model, POM),Maven 强制规定了项目的目录结构、构建生命周期和依赖管理方式。

  • 核心优势:统一的标准使不同开发者项目结构完全一致,极大降低了团队协作成本;XML 配置虽然冗长,但结构清晰、严谨

  • 适用场景:适合追求标准化、稳定性强的大型企业级项目,尤其是需要严格遵循规范的开发团队。

https://maven.apache.org/https://mvnrepository.com/

Gradle:灵活高效现代构建器

Gradle 是一款基于 Groovy 或 Kotlin DSL(领域特定语言)的构建工具。它继承了 Maven 和 Ant 的优点,摒弃了它们的缺点。

  • 核心优势:构建脚本极其灵活,支持增量构建和构建缓存,因此在大型项目中构建速度通常快于 Maven

  • 适用场景:适合对构建性能要求高、需要高度定制化构建逻辑、或使用多语言混合开发(如 Android、Kotlin 项目)的场景


标准化项目结构

在 Maven 出现之前,不同的 IDE(如 Eclipse, IntelliJ IDEA)往往有各自默认的项目目录结构,导致项目在不同环境间迁移困难。Maven 通过定义一套标准化的目录结构,解决了这一痛点。无论使用何种 IDE,只要遵循 Maven 规范,项目结构均保持一致。

核心目录结构详解

project-root/
├── src/                      # 源代码根目录
│   ├── main/                 # 主程序代码
│   │   ├── java/             # 存放 Java 源代码 (.java)
│   │   ├── resources/        # 存放配置文件 (如 .properties, .xml),编译后会复制到 classpath
│   │   └── webapp/           # (可选) Web 项目资源,如 JSP, HTML, CSS, JS
│   └── test/                 # 测试代码
│       ├── java/             # 存放测试类 (.java),通常使用 JUnit 或 TestNG
│       └── resources/        # 测试专用的配置文件
├── pom.xml                   # 【核心】项目对象模型配置文件,描述项目信息和构建逻辑
└── target/                   # 【生成】构建输出目录,包含编译后的 class 文件和打包后的 jar/war
  • src/main/resources:这里的文件在 mvn package 时会被原样复制到 target/classes 目录下,常用于存放数据库配置、日志配置等。

  • src/test/java:测试代码在此目录下,但不会被打包进最终的 JAR/WAR 文件中,仅在测试阶段生效。

  • target 目录:这是构建产物目录,通常会被添加到 .gitignore 中,不需要提交到版本控制系统。


标准化构建流程

软件开发涉及编译、测试、打包、部署等多个环节。Maven 将这些环节抽象为一个个 生命周期阶段,开发者只需执行对应的命令,Maven 会自动按顺序调用相应的 插件 完成任务。

核心构建命令

Maven 的命令通常对应生命周期的某个阶段,执行该阶段时,其之前的所有阶段也会自动执行。

  • mvn clean:清理 target 目录,删除之前的构建结果。

  • mvn compile:编译主代码 (src/main/java)。

  • mvn test:编译并运行单元测试。

  • mvn package:将代码打包成 JAR 或 WAR 文件(位于 target 目录)。

  • mvn install:将包安装到本地仓库,供其他本地项目引用。

  • mvn deploy:将包部署到远程仓库,供团队成员共享。

示例:执行 mvn package 时,Maven 会自动依次执行 validate -> compile -> test -> package。如果测试失败,构建过程会立即停止,不会进行打包。


依赖管理

依赖管理是 Maven 最核心的功能之一。它解决了手动下载 JAR 包、处理版本冲突和传递依赖的繁琐问题。

什么是“坐标”

在 Maven 世界中,每一个构件(JAR 包、插件等)都通过一组唯一的坐标来标识。这就像快递地址一样精准。
一个标准的坐标由以下三个核心元素组成(有时包含第四个 packaging):

  1. groupId:组织 ID,通常是公司域名的反写(如 com.mysql)。

  2. artifactId:项目 ID,具体模块或库的名称(如 mysql-connector-j)。

  3. version:版本号,遵循语义化版本规范(如 8.0.33)。

配置示例
要在项目中引入 MySQL 驱动,只需在 pom.xml<dependencies> 标签中添加:

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.0.33</version>
</dependency>

工作原理
当保存配置后,Maven 会根据坐标自动去仓库查找该 JAR 包。如果本地没有,它会从远程仓库下载并存入本地仓库。此外,Maven 还能自动处理传递依赖(Transitive Dependencies),即如果 A 依赖 B,B 依赖 C,那么引入 A 时,B 和 C 也会被自动下载。


仓库体系

Maven 仓库是存储所有构件(JAR 包、插件等)的地方。根据位置和用途,分为三类:

1. 本地仓库

  • 定义:位于开发者本机硬盘上的目录,用于缓存从远程下载的构件以及本地安装的构件。

  • 默认路径

    • Windows: C:\Users\<用户名>\.m2\repository

    • Linux/Mac: ~/.m2/repository

  • 配置:可通过修改全局或用户级的 settings.xml 文件中的 <localRepository> 标签来自定义路径。

  • 作用:加速构建,避免重复下载;离线开发时的依赖来源。

2. 中央仓库

  • 定义:由 Maven 社区维护的全球公共仓库,包含了绝大多数开源组件。

  • 特点

    • 无需配置即可使用(Maven 默认内置地址)。

    • 必须联网才能访问。

    • 镜像加速:由于中央仓库服务器位于国外,国内访问速度慢。通常建议在 settings.xml 中配置镜像 (Mirror),如阿里云镜像,以大幅提升下载速度。

3. 远程仓库 / 私服

  • 定义:由公司或团队自行搭建的仓库服务器(常用 Nexus 或 Artifactory)。

  • 用途

    • 存储公司内部开发的私有库。

    • 代理中央仓库,作为团队内部的缓存节点,节省带宽。

    • 存放中央仓库中没有的第三方商业闭源包。

  • 配置:在 pom.xmlsettings.xml 中通过 <repositories> 标签指定 URL。

依赖查找顺序

当 Maven 需要某个依赖时,遵循严格的查找顺序:

  1. 本地仓库:首先检查本地是否有该版本的构件。若有,直接使用;若无,进入下一步。

  2. 远程仓库:检查 pom.xmlsettings.xml 中配置的私有远程仓库。若找到,下载到本地仓库并使用。

  3. 中央仓库:若上述均未找到,则访问中央仓库(或其镜像)。若找到,下载到本地;若仍未找到,构建失败并报错 Could not resolve dependencies


构建生命周期

Maven 的生命周期是串行的,分为三个独立的生命周期:CleanDefault (Build)Site。其中最常用的是 Default 生命周期。

生命周期核心阶段

这是一个完整的构建流程,后续阶段依赖前序阶段的完成:

阶段

描述与作用

validate

校验:检查项目结构是否正确,必要信息是否完备。

compile

编译:将 src/main/java 下的源代码编译成 .class 字节码文件。

test

测试:编译 src/test/java 下的测试代码,并使用测试框架(如 JUnit)运行单元测试。
注意:此阶段不会将失败的测试打包,但会阻止后续阶段执行。

package

打包:将编译后的代码和资源文件打包成可分发的格式,如 JAR (Java Archive) 或 WAR (Web Archive)。

verify

验证:对集成测试的结果进行检查,确保包的质量符合标准。

install

安装:将生成的包(JAR/WAR)安装到本地仓库 (~/.m2/repository),使其可以被本机其他项目作为依赖引用。

deploy

部署:将最终的包复制到远程仓库(如 Nexus),供团队成员或其他项目使用。通常在 CI/CD 流水线中执行。

其他重要生命周期

  • Clean 生命周期:主要用于清理构建产物。

    • mvn clean:删除 target 目录。

    • mvn clean install:先清理旧构建,再重新编译、测试、打包并安装到本地仓库(最常用的组合命令)。

  • Site 生命周期:用于生成项目站点文档(如 JavaDoc、测试报告、依赖分析图等),现代开发中使用频率相对较低。

插件机制

Maven 本身只是一个框架,具体的任务(如编译、打包、测试)都是由插件完成的。

  • 编译插件maven-compiler-plugin,负责调用 JDK 编译器。

  • 打包插件maven-jar-pluginmaven-war-plugin

  • 测试插件maven-surefire-plugin,负责运行单元测试。

  • 自定义:开发者也可以编写自定义插件或配置现有插件的参数(如在 pom.xml 中指定 JDK 版本、跳过测试等)。