说明:这里的「效率」分为 打包速度(构建耗时)、增量构建效率、内存占用、产物大小、依赖处理能力、原生瘦身能力;测试基准:SpringBoot 3.x Java17 项目,常规 Web 工程 + 20~40 个三方依赖,区分 普通 JAR(非可执行) 和 胖 JAR(可执行 fat-jar)。
一、工具清单 & 核心原理
关键知识点:
不解压嵌套模式(SpringBoot bootJar/boot:repackage):依赖以
.jar原样嵌套在 BOOT-INF/lib,不需要解压所有依赖,CPU 开销低;解压合并模式(assembly /shadow):所有依赖全部解压,class 平铺,需要扫描、去重、SPI 合并、包重定位,CPU+IO 开销显著更高。
二、效率维度对比表
⚠️ 速度评分:⭐越快越好;产物大小:越小越好;增量:增量构建是否能跳过不变部分

三、耗时定性结论(实测经验值,Java17,40 个依赖 SpringBoot Web)
普通 thin jar(不含依赖)梯队
jdk jar≈maven jar≈gradle jar全量:几十 ms ~ 200ms 级别
Gradle Jar 增量:代码没改动直接跳过,几乎 0 耗时;Maven Jar 增量能力弱很多,Maven 靠
maven-compiler-plugin增量编译,打包阶段还是会执行。
SpringBoot 官方胖 Jar 梯队(嵌套模式)
Gradle bootJar>spring-boot-maven-plugin全量:1~4s(取决于依赖数量、磁盘 IO)
Gradle 优势:增量构建是最大亮点,只有 class / 资源变更才重新打包;Maven 本身没有 Task 输入输出快照,每次
package都会执行 repackage,缓存差。
解压合并型 FatJar(assembly /shadow)
assembly:全量 5~15s,依赖越多越慢;大量小文件解压、写入,磁盘 IO 瓶颈明显
ShadowJar:最慢,relocate 包重定位会逐 class 字节码改写;依赖多 + 大量 relocate 规则下几十秒都有可能
✅ 核心瓶颈拆解:
IO 瓶颈:解压大量 jar 包、成千上万 class 文件读写(assembly/shadow)
CPU 瓶颈:ShadowJar 字节码重定位、SPI 文件合并
构建模型瓶颈:Maven 是线性顺序执行、增量能力弱;Gradle 是基于输入输出(inputs/outputs)的增量 + 并行模型
四、产物大小对比重点
bootJar /boot:repackage:依赖是原 jar 原样嵌套,几乎不增加额外体积,只是打包封装;
assembly:解压平铺,如果多个依赖有同名资源(log 配置、META-INF),会覆盖或保留一份,体积略小 / 略大不稳定;
ShadowJar:relocate 会修改 class 常量池,class 文件体积会轻微变大;
thin jar:只有自己业务代码,体积最小。
五、内存占用
原生 jar/maven jar:几十 MB;
bootJar:几百 MB;
ShadowJar:很容易冲到 1G+,依赖多 + relocate 时,ASM 字节码处理吃堆内存,经常需要调
-Xmx。
六、调优手段(提升打包效率)
1)Maven boot 打包提速
<!-- 开启boot插件分层打包,同时支持构建缓存 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>enabled</layers>
<!-- 排除不需要的开发依赖,减少lib数量 -->
<excludes>...</excludes>
</configuration>
</plugin>
Maven 本身增量弱,方案:使用 maven-build-cache-extension 做远程 / 本地构建缓存。
2)Gradle bootJar 提速(收益最大)
开启守护进程
org.gradle.daemon=true开启构建缓存
org.gradle.caching=true并行
org.gradle.parallel=true对 bootJar 开启增量(默认已经支持,不要自己改写 outputs 破坏增量)
用
--offline、排除不必要依赖、runtimeOnly 精细化管理依赖
3)ShadowJar 提速
减少 relocate 规则,只对冲突包重定位,不要全局 relocate
开启
mergeServiceFiles()、exclude剔除无用资源给 Gradle 分配更大堆:
org.gradle.jvmargs=-Xmx2g
4)通用:优先分层镜像,而不是一味打包胖 JAR
SpringBoot Layered JAR:打包耗时几乎不变,但是 Docker 镜像分层推送拉取更快;很多人混淆「打包 JAR 速度」和「镜像分发效率」。

七、选型建议
内部 SDK、公共组件、不需要独立运行:Gradle Jar / maven-jar-plugin(最快)
SpringBoot Web 服务,线上部署:优先 Gradle bootJar;Maven 项目就用 spring-boot-maven-plugin
需要包名隔离、独立 CLI 工具、依赖版本冲突:ShadowJar(接受打包慢的代价)
老项目简单胖包,无复杂冲突:assembly(不推荐新项目)
极致简单脚本打包:jdk
jar命令
八、常见误区澄清
❌ 误区:ShadowJar 比 SpringBoot bootJar 更好 ✅ 正解:底层模型完全不同;bootJar 是嵌套 jar launcher,打包速度快、无字节码修改;ShadowJar 是解压合并 + 字节码改写,代价很高,只解决包冲突场景。
❌ 误区:Maven 打包一定比 Gradle 慢 ✅ 正解:全量打包差距不大;增量场景差距巨大,Gradle 增量模型是天然优势。
❌ 误区:胖 JAR 越小包越快 ✅ 正解:打包速度主要看「是否解压依赖、是否字节码改写」,不是单纯体积。
本文原创作者:易君召,详见:https://www.yijunzhao.cn/authors/yijunzhao,转载请注明出处。
原文链接
欢迎访问 小易撩挨踢