前置知识: Java

Java构建工具

5 minIntermediate2026/6/14

Maven与Gradle

概述

Java 构建工具负责管理项目的依赖、编译源码、运行测试、打包发布等一系列任务。没有构建工具时,你需要手动下载 jar 包、手动编译、手动组织目录结构,效率极低。构建工具把这些重复性工作自动化,让你专注于编写代码。

Java 生态中有两个主流构建工具:Maven 和 Gradle。Maven 是老牌工具,使用 XML 配置,约定严格,社区资源丰富;Gradle 是后起之秀,使用 Groovy/Kotlin DSL 配置,更灵活,构建速度更快。新项目可以根据团队偏好选择,两者都能胜任。

基础概念

依赖管理

Java 项目通常依赖大量第三方库(如 Spring、Jackson、MySQL 驱动等)。构建工具通过坐标(groupId、artifactId、version)从仓库(Maven Central 或私有仓库)自动下载这些依赖,并处理依赖之间的传递关系。

仓库

仓库是存放 jar 包的地方。Maven Central 是最大的公共仓库,几乎所有开源 Java 库都发布在这里。企业通常还会搭建私有仓库(如 Nexus、Artifactory)来存放内部组件。

生命周期

Maven 定义了标准的构建生命周期:validate -> compile -> test -> package -> verify -> install -> deploy。每个阶段由插件的具体目标(goal)实现。执行某个阶段时,它之前的所有阶段会自动执行。

模块项目

大型项目通常拆分为多个模块(如 api、service、common),每个模块有独立的 pom.xml 或 build.gradle,但由父项目统一管理依赖版本和构建流程。

快速上手

Maven 项目结构

Maven 约定了标准的目录结构:

my-project/
├── pom.xml              # 项目配置文件
├── src/
│   ├── main/
│   │   ├── java/        # Java 源码
│   │   └── resources/   # 配置文件、静态资源
│   └── test/
│       ├── java/        # 测试代码
│       └── resources/   # 测试资源
└── target/              # 编译输出(自动生成)

最简 pom.xml

<?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
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 项目坐标 -->
    <groupId>com.example</groupId>
    <artifactId>my-project</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <!-- 继承 Spring Boot 父项目,获得默认配置和依赖版本管理 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
    </parent>

    <dependencies>
        <!-- Spring Boot Web Starter -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>

常用 Maven 命令

# 编译项目
mvn compile

# 运行测试
mvn test

# 打包(编译 + 测试 + 生成 jar)
mvn package

# 清理之前的构建结果
mvn clean

# 清理并打包(最常用)
mvn clean package

# 安装到本地仓库(供其他项目引用)
mvn install

# 跳过测试打包(紧急发布时使用)
mvn clean package -DskipTests

# 查看依赖树(排查依赖冲突)
mvn dependency:tree

详细用法

1. Maven 依赖管理

<dependencies>
    <!-- 基本依赖:groupId + artifactId + version -->
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>33.0.0-jre</version>
    </dependency>

    <!-- scope 控制依赖的作用范围 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>5.10.0</version>
        <scope>test</scope>  <!-- 只在测试时使用,不会打包到最终 jar -->
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>  <!-- 由运行环境提供(如 Tomcat),不打包 -->
    </dependency>

    <!-- 排除传递依赖 -->
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>some-library</artifactId>
        <version>1.0.0</version>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <!-- 排除这个传递依赖,避免与项目使用的日志框架冲突 -->
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

2. Maven 依赖版本管理

在多模块项目中,统一管理依赖版本很重要:

<!-- 在父 pom.xml 中使用 dependencyManagement 管理版本 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>33.0.0-jre</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.14.0</version>
        </dependency>
    </dependencies>
</dependencyManagement>

<!-- 子模块中不需要指定版本,统一使用父项目定义的版本 -->
<dependencies>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <!-- 不需要写 version,由父项目管理 -->
    </dependency>
</dependencies>

3. Maven 多模块项目

<!-- 父项目 pom.xml -->
<groupId>com.example</groupId>
<artifactId>my-project-parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>  <!-- 父项目的打包类型是 pom -->

<modules>
    <module>api</module>      <!-- API 模块 -->
    <module>service</module>  <!-- 业务逻辑模块 -->
    <module>common</module>   <!-- 公共工具模块 -->
</modules>

模块的 pom.xml:

<!-- api/pom.xml -->
<parent>
    <groupId>com.example</groupId>
    <artifactId>my-project-parent</artifactId>
    <version>1.0.0</version>
</parent>

<artifactId>my-project-api</artifactId>

<dependencies>
    <!-- 依赖同项目的 common 模块 -->
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>my-project-common</artifactId>
        <version>${project.version}</version>
    </dependency>
</dependencies>

4. Gradle 项目结构

Gradle 的项目结构与 Maven 相同,但配置文件是 build.gradle:

// build.gradle
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.0'
    id 'io.spring.dependency-management' version '1.1.4'
}

group = 'com.example'
version = '1.0.0'

java {
    sourceCompatibility = '17'  // Java 版本
}

// 仓库配置
repositories {
    mavenCentral()  // Maven Central 仓库
    // maven { url 'https://maven.aliyun.com/repository/public' }  // 阿里云镜像
}

// 依赖配置
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.google.guava:guava:33.0.0-jre'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

5. Gradle 依赖范围

Gradle 的依赖范围比 Maven 更细粒度:

dependencies {
    // implementation:编译和运行时都需要,但不会传递给依赖此模块的其他模块
    implementation 'com.google.guava:guava:33.0.0-jre'

    // api:编译和运行时都需要,且会传递给依赖此模块的其他模块
    api 'com.example:my-common-lib:1.0.0'

    // compileOnly:只在编译时需要,运行时由环境提供
    compileOnly 'org.projectlombok:lombok:1.18.30'

    // runtimeOnly:只在运行时需要,编译时不需要(如数据库驱动)
    runtimeOnly 'com.mysql:mysql-connector-j:8.3.0'

    // testImplementation:只在测试编译和运行时需要
    testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'

    // annotationProcessor:注解处理器(如 Lombok)
    annotationProcessor 'org.projectlombok:lombok:1.18.30'
}

6. Gradle 常用命令

# 编译项目
gradle build

# 清理构建结果
gradle clean

# 运行测试
gradle test

# 查看依赖树
gradle dependencies

# 刷新依赖(强制重新下载)
gradle build --refresh-dependencies

# 不运行测试打包
gradle build -x test

7. Gradle 多模块项目

// settings.gradle(根目录)
rootProject.name = 'my-project'
include 'api', 'service', 'common'
// api/build.gradle
dependencies {
    implementation project(':common')  // 依赖同项目的 common 模块
}

8. Maven 私有仓库配置

企业项目通常需要发布到私有仓库:

<!-- pom.xml 中配置分发管理 -->
<distributionManagement>
    <repository>
        <id>company-releases</id>
        <url>https://nexus.company.com/repository/releases/</url>
    </repository>
    <snapshotRepository>
        <id>company-snapshots</id>
        <url>https://nexus.company.com/repository/snapshots/</url>
    </snapshotRepository>
</distributionManagement>
# 发布到私有仓库
mvn deploy

常见场景

场景一:解决依赖冲突

当多个库间接依赖同一个库的不同版本时,会产生冲突:

# Maven:查看依赖树找到冲突
mvn dependency:tree -Dincludes=com.fasterxml.jackson.core:jackson-databind

# 找到冲突后,用 exclusion 排除不需要的版本
# 或者在 dependencyManagement 中强制指定版本
// Gradle:查看依赖冲突
gradle dependencies --configuration runtimeClasspath

// 强制指定版本
configurations.all {
    resolutionStrategy {
        force 'com.fasterxml.jackson.core:jackson-databind:2.16.0'
    }
}

场景二:使用国内镜像加速

国内访问 Maven Central 较慢,可以配置阿里云镜像:

<!-- ~/.m2/settings.xml -->
<mirrors>
    <mirror>
        <id>aliyun</id>
        <mirrorOf>central</mirrorOf>
        <url>https://maven.aliyun.com/repository/public</url>
    </mirror>
</mirrors>

注意事项与常见错误

依赖范围不要搞错

Maven 的 scope 和 Gradle 的 configuration 容易混淆。最常见的错误是把应该用 implementation 的依赖写成了 api,导致依赖泄露,其他模块无意中依赖了不应该看到的内部库。

SNAPSHOT 版本的风险

SNAPSHOT 版本是不稳定的开发版本,每次构建可能获取到不同的代码。生产环境绝不能依赖 SNAPSHOT 版本,应该使用正式发布的版本。

不要把构建工具的配置文件提交时忽略

target/ 和 build/ 目录应该加入 .gitignore,但 pom.xml、build.gradle、settings.gradle 必须提交到版本控制。

Gradle Wrapper

使用 Gradle Wrapper 可以确保所有开发者使用相同的 Gradle 版本:

# 生成 Wrapper
gradle wrapper

# 使用 Wrapper 代替本地 Gradle
./gradlew build  # Linux/Mac
gradlew.bat build  # Windows

进阶用法

Maven BOM 依赖管理

BOM(Bill of Materials)是一种特殊的 pom,只包含 dependencyManagement,用于统一管理一组相关依赖的版本:

<!-- 导入 Spring Cloud BOM -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2023.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Gradle 构建缓存

Gradle 支持构建缓存,可以显著加快构建速度:

// gradle.properties
org.gradle.caching=true        // 启用构建缓存
org.gradle.parallel=true       // 并行构建模块
org.gradle.jvmargs=-Xmx2g     // 增加 Gradle 的 JVM 内存

自定义 Maven 插件

当标准插件不满足需求时,可以编写自定义插件:

<!-- 使用 exec-maven-plugin 在构建时执行自定义命令 -->
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>exec</goal>
            </goals>
            <configuration>
                <executable>npm</executable>
                <arguments>
                    <argument>run</argument>
                    <argument>build</argument>
                </arguments>
            </configuration>
        </execution>
    </executions>
</plugin>