Java构建工具对比:Maven vs Gradle,到底该选哪个?

作为一名Java开发者,你一定每天在和构建工具打交道。
Maven和Gradle,这两个名字几乎成了Java世界的代名词。它们都能帮我们管理依赖、编译代码、打包发布,但两者之间到底有什么区别?为什么有的项目用Maven,有的用Gradle?XML和Groovy,哪个更好?
今天这篇文章,我会用最通俗的方式,带你彻底搞懂:
-
构建工具到底是干什么的
-
Maven和Gradle的核心差异
-
两者的配置文件长什么样
-
如何用它们打包出可运行的Jar包
-
构建产物都存放在哪里
无论你是刚入门Java的新手,还是想从Maven迁移到Gradle的老手,这篇文章都适合你。
一、构建工具:Java项目的“总管家”
在Java世界里,一个项目远不止你写的那些代码。它还包括:
-
几十甚至上百个第三方依赖(Spring、Log4j、MySQL驱动等)
-
配置文件
-
资源文件
-
测试代码
-
各种需要自动化执行的任务
如果这些都要手动管理,那开发效率将低得可怕。
构建工具就是来解决这些问题的。它的核心工作包括:
-
自动安装依赖:根据配置文件,从中央仓库下载所有需要的jar包
-
编译源代码:把.java文件编译成.class字节码
-
运行测试:自动执行单元测试并生成报告
-
打包制品:把编译后的代码和所有依赖打包成可部署的Jar/War文件
-
压缩体积:优化打包结果,让制品更小、传输更快
-
执行自定义任务:比如代码生成、静态检查等
Java生态中最主流的两个构建工具,就是Maven和Gradle。
二、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>
关键元素:
-
groupId、artifactId、version:项目的唯一坐标 -
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,都能得心应手。
更多推荐




所有评论(0)