作为一名Java开发者,你一定每天在和构建工具打交道。

Maven和Gradle,这两个名字几乎成了Java世界的代名词。它们都能帮我们管理依赖、编译代码、打包发布,但两者之间到底有什么区别?为什么有的项目用Maven,有的用Gradle?XML和Groovy,哪个更好?

今天这篇文章,我会用最通俗的方式,带你彻底搞懂:

  • 构建工具到底是干什么的

  • Maven和Gradle的核心差异

  • 两者的配置文件长什么样

  • 如何用它们打包出可运行的Jar包

  • 构建产物都存放在哪里

无论你是刚入门Java的新手,还是想从Maven迁移到Gradle的老手,这篇文章都适合你。

一、构建工具:Java项目的“总管家”

在Java世界里,一个项目远不止你写的那些代码。它还包括:

  • 几十甚至上百个第三方依赖(Spring、Log4j、MySQL驱动等)

  • 配置文件

  • 资源文件

  • 测试代码

  • 各种需要自动化执行的任务

如果这些都要手动管理,那开发效率将低得可怕。

构建工具就是来解决这些问题的。它的核心工作包括:

  1. 自动安装依赖:根据配置文件,从中央仓库下载所有需要的jar包

  2. 编译源代码:把.java文件编译成.class字节码

  3. 运行测试:自动执行单元测试并生成报告

  4. 打包制品:把编译后的代码和所有依赖打包成可部署的Jar/War文件

  5. 压缩体积:优化打包结果,让制品更小、传输更快

  6. 执行自定义任务:比如代码生成、静态检查等

Java生态中最主流的两个构建工具,就是MavenGradle

二、Maven vs Gradle:核心差异对比
对比维度 Maven Gradle
配置文件语言 XML Groovy(或Kotlin)
灵活性 约定优于配置,结构固定 高度灵活,支持自定义任务
学习曲线 平缓,XML容易上手 较陡,需要学习Groovy语法
性能 较慢,尤其是大型项目 更快,支持增量构建
构建命令 mvn clean install gradle build
输出目录 target/ build/
依赖管理 基于中央仓库,版本固定 支持动态版本,更灵活

1. 配置文件语言:XML vs Groovy

这是两者最本质的区别。

Maven使用XML。配置文件叫pom.xml(Project Object Model)。XML的特点是结构清晰、严格规范,但写起来比较啰嗦,尤其是要自定义复杂任务时,XML会变得非常冗长。

Gradle使用Groovy(也可以选Kotlin)。配置文件叫build.gradle。Groovy是一种脚本语言,语法简洁,可以直接写逻辑代码。这让Gradle在自定义构建任务时异常灵活——你可以像写程序一样写构建脚本。

举个例子,如果你想在构建时打印当前时间:

Maven需要写一个插件,配置一堆XML;
Gradle只需要在build.gradle里加一行println new Date()

这就是Gradle的核心优势:脚本式配置,灵活便捷

2. 构建命令与输出目录

两者命令不同,但逻辑一致:

  • Maven构建mvn clean install(或mvn clean package

  • Gradle构建gradle build

构建成功后,产物存放的位置也不同:

  • Maven:输出到项目根目录下的target/文件夹

  • Gradle:输出到项目根目录下的build/文件夹

具体来说,可运行的Jar包在:

  • Maven:target/项目名-版本号.jar

  • Gradle:build/libs/项目名-版本号.jar

三、Maven实战:从配置到打包

1. Maven项目核心文件:pom.xml

一个典型的pom.xml长这样:

<project>
    <groupId>com.example</groupId>
    <artifactId>java-maven-app</artifactId>
    <version>1.1.0-SNAPSHOT</version>
    
    <dependencies>
        <!-- 这里声明项目依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.7.0</version>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>3.0.5</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

关键元素:

  • groupIdartifactIdversion:项目的唯一坐标

  • dependencies:项目依赖声明

  • build/plugins:构建插件,比如Spring Boot的打包插件

2. 执行构建

在项目根目录(包含pom.xml的目录)执行:

mvn clean install

3. 查看构建结果

构建成功后,你会看到BUILD SUCCESS的提示。此时项目目录下会多出一个target/文件夹:

target/
├── classes/                 # 编译后的字节码
├── generated-sources/       # 生成的源代码
├── java-maven-app-1.1.0-SNAPSHOT.jar     # 可执行Jar包
├── java-maven-app-1.1.0-SNAPSHOT.jar.original  # 未打包依赖的原始Jar
└── ...

其中java-maven-app-1.1.0-SNAPSHOT.jar就是我们需要的可部署制品。这个Jar包包含了应用的所有代码和依赖,可以直接通过java -jar命令运行。

四、Gradle实战:从配置到打包

1. Gradle项目核心文件:build.gradle

一个典型的build.gradle长这样:

plugins {
    id 'org.springframework.boot' version '2.7.0'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

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

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
    useJUnitPlatform()
}

Groovy语法的特点:

  • 更简洁,没有XML的尖括号

  • 可以直接写方法调用和闭包

  • 支持自定义任务,比如:

task printDate {
    doLast {
        println new Date()
    }
}

2. 执行构建

在项目根目录(包含build.gradle的目录)执行:

gradle build

3. 查看构建结果

构建成功后,你会看到BUILD SUCCESSFUL的提示。此时项目目录下会多出一个build/文件夹:

build/
├── classes/           # 编译后的字节码
├── libs/              # 打包好的Jar文件
│   └── java-app-1.0-SNAPSHOT.jar
├── reports/           # 测试报告等
└── ...

build/libs/java-app-1.0-SNAPSHOT.jar就是Gradle产出的可运行Jar包。

五、一个完整的Java应用长什么样

让我们看看一个简单的Spring Boot应用的代码:

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.PostConstruct;

@SpringBootApplication
public class App {
    
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
    
    @PostConstruct
    public void init() {
        System.out.println("应用启动完成!");
        // 这里可以写一些初始化代码
    }
}

这个类有main方法,是应用的入口。加上@SpringBootApplication注解,就声明了一个Spring Boot应用。

通过构建工具打包后,这个类的字节码会连同所有依赖一起被打包进Jar文件。运行时,java -jar命令会找到这个main方法并启动应用。

六、如何选择:Maven还是Gradle?

选Maven的场景:

  • 项目结构标准,不需要太多自定义任务

  • 团队熟悉XML,不想学习新语法

  • 项目规模中等,对构建速度要求不高

  • 需要严格遵守约定,不希望太灵活导致混乱

选Gradle的场景:

  • 项目规模大,对构建速度有要求(Gradle的增量构建优势明显)

  • 需要大量自定义构建逻辑

  • 喜欢简洁的DSL语法,不喜欢XML的冗余

  • 团队愿意学习新技术

一句话总结:

  • Maven是规矩的老大哥,稳定、标准、易上手

  • Gradle是灵活的年轻人,快速、简洁、功能强大

无论选哪个,都能完成Java项目的构建任务。关键是理解它们的设计哲学,然后根据项目需求做选择。

七、总结:一张表记住核心要点
项目 Maven Gradle
配置文件 pom.xml build.gradle
配置语言 XML Groovy/Kotlin
构建命令 mvn clean install gradle build
输出目录 target/ build/
Jar包位置 target/目录下 build/libs/目录下
灵活性 较低,需插件 较高,可写脚本
性能 一般 更快(增量构建)

不同构建工具对应不同的配置和目录规则,但核心目标都是一样的——打包出包含所有依赖的可执行制品

理解了这一点,无论你用Maven还是Gradle,都能得心应手。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐