
一、什么是缩小打包体积缩小打包体积是指通过各种优化手段减少Spring Boot应用最终部署包通常是JAR文件的大小。这在微服务架构和云原生部署场景中尤为重要主要体现在以下几个方面1.1 核心概念原始问题Spring Boot默认采用胖JAR打包方式将所有依赖Spring框架、业务代码、嵌入式服务器、第三方库全部打成一个可执行JAR体积通常在50MB-200MB之间优化目标通过分离依赖、精简内容、分层构建等方式将部署包体积缩小30%-80%1.2 为什么重要部署效率更小的包意味着更快的上传、下载和部署速度存储成本减少镜像仓库和服务器存储空间占用启动速度精简后的包加载类文件更快减少启动时间CI/CD效率缩短构建和发布流水线时间网络传输特别是在带宽有限的环境下小体积包优势明显容器化部署更小的镜像体积意味着更快的拉取和扩展速度二、缩小打包体积的详细步骤2.1 依赖优化步骤1分析和精简依赖!-- pom.xml -- project !-- 使用Maven依赖分析插件 -- build plugins plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-dependency-plugin/artifactId version3.5.0/version executions execution idanalyze/id goals goalanalyze/goal /goals /execution /executions /plugin /plugins /build /project步骤2排除不必要的依赖!-- 排除Tomcat如果使用Jetty或Undertow -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId exclusions exclusion groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-tomcat/artifactId /exclusion /exclusions /dependency !-- 添加轻量级的Undertow替代 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-undertow/artifactId /dependency2.2 使用Spring Boot分层JAR步骤3配置分层JAR!-- pom.xml - 使用Spring Boot 2.3的分层特性 -- build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId configuration layers enabledtrue/enabled configuration${project.basedir}/layers.xml/configuration /layers /configuration /plugin /plugins /build创建自定义分层配置layers.xmllayers xmlnshttp://www.springframework.org/schema/boot/layers xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://www.springframework.org/schema/boot/layers https://www.springframework.org/schema/boot/layers/layers-2.3.xsd application into layerspring-boot-loader includeorg/springframework/boot/loader/**/include /into into layerapplication / /application dependencies into layersnapshot-dependencies include*:*:*SNAPSHOT/include /into into layerinternal-dependencies includecom.yourcompany:*/include /into into layerdependencies / /dependencies layerOrder layerdependencies/layer layerspring-boot-loader/layer layersnapshot-dependencies/layer layerinternal-dependencies/layer layerapplication/layer /layerOrder /layers2.3 构建Docker镜像优化步骤4创建优化的Dockerfile# 使用多阶段构建 # 构建阶段 FROM maven:3.8.4-openjdk-11-slim AS builder WORKDIR /app COPY pom.xml . # 下载依赖利用Docker缓存 RUN mvn dependency:go-offline COPY src ./src # 打包应用 RUN mvn clean package -DskipTests # 运行阶段 FROM openjdk:11-jre-slim WORKDIR /app # 创建非root用户 RUN addgroup --system --gid 1001 appuser \ adduser --system --uid 1001 --gid 1001 appuser # 从构建阶段复制JAR COPY --frombuilder --chownappuser:appuser /app/target/*.jar app.jar # 提取分层JAR RUN java -Djarmodelayertools -jar app.jar extract # 复制分层内容 COPY --frombuilder --chownappuser:appuser /app/dependencies/ ./ COPY --frombuilder --chownappuser:appuser /app/spring-boot-loader/ ./ COPY --frombuilder --chownappuser:appuser /app/snapshot-dependencies/ ./ COPY --frombuilder --chownappuser:appuser /app/application/ ./ USER appuser # 优化JVM参数 ENTRYPOINT [java, -XX:UseContainerSupport, -XX:MaxRAMPercentage75.0, -XX:UseG1GC, -XX:OptimizeStringConcat, -XX:UseStringDeduplication, org.springframework.boot.loader.JarLauncher]2.4 资源文件优化步骤5优化静态资源和配置文件!-- 在pom.xml中配置资源过滤和压缩 -- build resources resource directorysrc/main/resources/directory filteringtrue/filtering excludes exclude**/*.psd/exclude exclude**/*.ai/exclude exclude**/*.xcf/exclude /excludes /resource /resources plugins !-- 压缩CSS/JS -- plugin groupIdcom.github.eirslett/groupId artifactIdfrontend-maven-plugin/artifactId version1.12.1/version executions execution idcompress-resources/id goals goalyarn/goal /goals configuration argumentsbuild/arguments /configuration /execution /executions /plugin /plugins /build2.5 自定义ClassLoader和数据压缩步骤6实现自定义类加载器// 自定义类加载器实现懒加载 public class LazyLoadingClassLoader extends ClassLoader { private MapString, byte[] classBytesMap new ConcurrentHashMap(); public void registerClassBytes(String className, byte[] bytes) { classBytesMap.put(className, bytes); } Override protected Class? findClass(String name) throws ClassNotFoundException { byte[] bytes classBytesMap.remove(name); if (bytes null) { return super.findClass(name); } return defineClass(name, bytes, 0, bytes.length); } }步骤7配置文件压缩Configuration PropertySource(value classpath:application.properties, encoding UTF-8) public class CompressedConfig { Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { PropertySourcesPlaceholderConfigurer configurer new PropertySourcesPlaceholderConfigurer(); // 启用压缩属性文件 configurer.setIgnoreUnresolvablePlaceholders(true); configurer.setFileEncoding(UTF-8); return configurer; } }2.6 使用GraalVM Native Image步骤8配置GraalVM原生编译!-- 添加native-image插件 -- plugin groupIdorg.graalvm.buildtools/groupId artifactIdnative-maven-plugin/artifactId version0.9.20/version extensionstrue/extensions configuration buildArgs buildArg-H:ReportExceptionStackTraces/buildArg buildArg--initialize-at-build-timeorg.springframework.util.unit.DataSize/buildArg buildArg--initialize-at-build-timeorg.slf4j/buildArg /buildArgs /configuration executions execution idbuild-native/id goals goalcompile-no-fork/goal /goals phasepackage/phase /execution /executions /plugin2.7 自动化瘦身脚本步骤9创建自动化瘦身脚本#!/bin/bash # slim-down.sh - 自动化瘦身脚本 echo 开始Spring Boot应用瘦身... # 1. 分析当前JAR大小 JAR_FILE$(ls target/*.jar | head -1) ORIGINAL_SIZE$(du -h $JAR_FILE | cut -f1) echo 原始JAR大小: $ORIGINAL_SIZE # 2. 提取并分析依赖 mkdir -p tmp/unpacked cd tmp/unpacked jar -xf ../../$JAR_FILE cd BOOT-INF/lib # 3. 找出大文件依赖 echo 前10大依赖: ls -lhS | head -10 # 4. 分析可移除的依赖 cd ../../.. rm -rf tmp # 5. 重新打包使用分层JAR echo 执行分层JAR打包... mvn clean package -Dspring-boot.thin.jartrue # 6. 构建优化后的Docker镜像 echo 构建优化镜像... docker build -t optimized-app:latest -f Dockerfile.multistage . NEW_JAR$(ls target/*.jar | head -1) NEW_SIZE$(du -h $NEW_JAR | cut -f1) REDUCTION$(echo scale2; ($(du -b $JAR_FILE | cut -f1) - $(du -b $NEW_JAR | cut -f1)) / $(du -b $JAR_FILE | cut -f1) * 100 | bc) echo 优化完成! echo 原始大小: $ORIGINAL_SIZE echo 优化后大小: $NEW_SIZE echo 体积减少: $REDUCTION%2.8 使用Thin Launcher步骤10配置Thin Launcher!-- 使用Spring Boot Thin Launcher -- build plugins plugin groupIdorg.springframework.boot.experimental/groupId artifactIdspring-boot-thin-maven-plugin/artifactId version1.0.29.RELEASE/version executions execution idresolve/id goals goalresolve/goal /goals inheritedfalse/inherited /execution /executions /plugin !-- 修改默认打包插件 -- plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-jar-plugin/artifactId configuration archive manifest mainClass${start-class}/mainClass /manifest manifestEntries Spring-Boot-Version${spring-boot.version}/Spring-Boot-Version Spring-Boot-Liblib//Spring-Boot-Lib /manifestEntries /archive /configuration /plugin /plugins /build2.9 配置排除和瘦身优化步骤11完整的pom.xml优化配置?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion groupIdcom.example/groupId artifactIdslim-app/artifactId version1.0.0/version packagingjar/packaging parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.7.0/version /parent properties java.version11/java.version !-- 启用瘦身模式 -- spring-boot.thin.jartrue/spring-boot.thin.jar !-- 排除devtools -- spring-boot.devtools.excludetrue/spring-boot.devtools.exclude /properties dependencies !-- 核心依赖排除不必要的传递依赖 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId exclusions exclusion groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-tomcat/artifactId /exclusion exclusion groupIdorg.hibernate.validator/groupId artifactIdhibernate-validator/artifactId /exclusion exclusion groupIdorg.springframework/groupId artifactIdspring-webmvc/artifactId /exclusion /exclusions /dependency !-- 使用轻量级服务器 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-jetty/artifactId /dependency !-- 条件化引入依赖 -- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional scopeprovided/scope /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId configuration !-- 启用分层JAR -- layers enabledtrue/enabled /layers !-- 排除devtools -- excludeDevtoolstrue/excludeDevtools !-- 配置需要排除的依赖 -- excludes exclude groupIdorg.projectlombok/groupId artifactIdlombok/artifactId /exclude /excludes /configuration /plugin !-- 依赖分析插件 -- plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-dependency-plugin/artifactId version3.5.0/version executions execution idanalyze-dependencies/id goals goalanalyze-only/goal /goals configuration failOnWarningfalse/failOnWarning /configuration /execution /executions /plugin !-- 资源优化插件 -- plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-resources-plugin/artifactId version3.3.1/version configuration encodingUTF-8/encoding nonFilteredFileExtensions nonFilteredFileExtensionpdf/nonFilteredFileExtension nonFilteredFileExtensionpng/nonFilteredFileExtension nonFilteredFileExtensionjpg/nonFilteredFileExtension /nonFilteredFileExtensions /configuration /plugin /plugins /build /project三、详细总结3.1 优化效果对比优化策略原始体积优化后体积缩减比例适用场景基础依赖精简80MB60MB25%所有项目分层JAR 多阶段构建80MB45MB44%容器部署Thin Launcher80MB15MB81%微服务GraalVM Native80MB25MB69%高性能场景综合优化80MB18MB78%云原生部署3.2 最佳实践总结优先级策略第一优先级立即实施使用spring-boot-maven-plugin的分层JAR功能排除不必要的传递依赖使用多阶段Docker构建第二优先级推荐实施替换为轻量级嵌入式服务器Undertow/Jetty配置资源过滤和排除使用maven-dependency-plugin分析并移除无用依赖第三优先级可选实施采用Thin Launcher方案使用GraalVM Native Image实现自定义类加载器3.3 关键注意事项1. 兼容性考量Native Image对反射、动态代理支持有限Thin Launcher可能需要调整类加载逻辑分层JAR需要Spring Boot 2.32. 性能权衡Native Image启动快但构建慢Thin Launcher首次启动需要下载依赖过度精简可能影响功能完整性3. 监控与维护建立体积监控基准在CI/CD流程中自动检查JAR大小定期review依赖使用情况