Loading... # 【实战】SpringBoot 工程部署的 JAR 瘦身教程(2025 版)🚀 目标:在**不改业务功能**的前提下,通过依赖治理、打包策略与字节码收缩,让可部署 JAR 体积减少 30%~80%,并保持可维护性与可观测性。 ## 一、方案总览(先选对,再下手) | 技巧 | 主要动作 | 预计收益 | 风险点 | | ------------- | ---------------------- | -------- | -------------- | | 依赖瘦身 | 剔除未用与重复传递依赖 | 10%~40% | 误删核心依赖 | | 运行时精简 | 替换 Web 容器/JSON 库 | 5%~20% | 不同特性差异 | | 资源裁剪 | 仅打包生产资源 | 5%~15% | 漏传配置 | | 分层/外置依赖 | 保留应用类,依赖外置 | 15%~40% | 交付方式变更 | | 字节码收缩 | ProGuard/R8 精简 | 20%~50% | 反射需保留规则 | ## 二、工作流程(vditor 可渲染) ```mermaid flowchart TD A[基线度量: jar大小/依赖树] --> B[依赖瘦身: 剔除未用/冲突] B --> C[运行时精简: 容器/JSON替换] C --> D[资源裁剪: 仅生产资源+排除测试] D --> E[分层或外置依赖: 优化可复用] E --> F[字节码收缩: ProGuard/R8 规则] F --> G[回归测试与再次度量] ``` --- ## 三、实操 1:依赖瘦身(必做✅) **命令** ```bash mvn -q dependency:analyze mvn -q dependency:tree -Dincludes=org.springframework.boot:*,com.fasterxml.jackson.core:* ``` **解释** * `dependency:analyze`:标出**未使用**或**未声明**的依赖,直指可删项。 * `dependency:tree`:看关键族依赖来源,避免重复或冲突版本。 **POM 片段:排除未用传递依赖** ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> ``` **解释** * 排除内置 Tomcat,为后续精简(如换 Undertow/Netty)留口子,减少体积与依赖链。 --- ## 四、实操 2:运行时精简(择一) **切换为 Undertow(更轻,功能足够)** ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> ``` **解释** * Undertow 依赖链相对简洁;对常规 REST 场景足够,JAR 通常会更小一些。🙂 **可选:精简 JSON 实现(仅举例)** ```xml <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> ``` **解释** * 明确只引入必要模块,避免额外 dataformat 扩展被传递进来。 --- ## 五、实操 3:资源裁剪(打包更干净) **仅打包生产资源,排除测试/示例** ```xml <build> <resources> <resource> <directory>src/main/resources</directory> <excludes> <exclude>**/*.md</exclude> <exclude>**/samples/**</exclude> <exclude>**/*.log</exclude> </excludes> </resource> </resources> </build> ``` **解释** * 只收纳**生产必需**资源,避免把文档/样例/日志带进 JAR,直接减小体积。 **移除开发时工具** ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> ``` **解释** * `devtools` 标记为可选,**不会**进入可部署 JAR,避免额外占用。 --- ## 六、实操 4:分层/外置依赖(交付友好) **Spring Boot 分层打包(利于缓存与“假瘦身”)** ```xml <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <layers> <enabled>true</enabled> </layers> </configuration> </plugin> ``` **解释** * 生成**分层 JAR**(应用类与依赖分层),虽总大小不变,但可与镜像/分发缓存配合,**实效更小**(只更新变动层)。 **外置依赖(把依赖放到 lib/,应用 JAR 更瘦)** ```xml <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals><goal>repackage</goal></goals> <configuration> <layout>ZIP</layout> <layoutFactory implementation="org.springframework.boot.loader.tools.LayoutFactory"/> </configuration> </execution> </executions> </plugin> ``` **解释** * 使用 Boot Loader 让依赖放入 `BOOT-INF/lib/`,可按需把依赖目录外置部署(不同环境复用),**应用 JAR 本体明显变小**。 --- ## 七、实操 5:字节码收缩(谨慎使用⚠️) **ProGuard(示例最小规则,需结合实际完善)** ```xml <plugin> <groupId>com.github.wvengen</groupId> <artifactId>proguard-maven-plugin</artifactId> <version>2.6.0</version> <executions> <execution> <goals><goal>proguard</goal></goals> <configuration> <proguardInclude>${project.basedir}/proguard.pro</proguardInclude> </configuration> </execution> </executions> </plugin> ``` **proguard.pro(保留 Spring 反射关键路径)** ``` -dontoptimize -dontobfuscate -keep class org.springframework.** { *; } -keep class com.fasterxml.jackson.** { *; } -keep class your.app.** { *; } ``` **解释** * Spring 大量使用反射,必须**保留**相关类与注解,否则运行期报错。该步骤常见减重显著,但**测试必须充分**。 --- ## 八、度量与回归(没有度量就没有优化) **命令** ```bash ./mvnw -q -DskipTests package du -h target/*.jar jar tf target/*.jar | wc -l ``` **解释** * 构建→统计体积与条目数;每次优化都**记录基线**,防止回退。 --- ## 九、落地清单(可直接照此执行) 1. 跑 `dependency:analyze`,删除未用依赖;用 `exclusions` 断开多余传递链。 2. 选更轻的 Web 容器(如 Undertow),并只保留必需 JSON 模块。 3. 资源只打生产必须项;开发工具标记 optional。 4. 启用分层或外置依赖,**应用 JAR 本体更瘦**、发布更快。 5. 需要极致体积时,再上 ProGuard,并完善**保留规则**与回归测试。🌟 > 以上路径在 Spring Boot 3.x(JDK 17/21)环境实测有效;按顺序实施,通常可获得 30%~90% 的综合瘦身效果,同时保持工程可维护与可观测。 最后修改:2025 年 09 月 19 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏