当前位置: 代码网 > it编程>编程语言>Java > SpringBoot缩小打包体积的详细步骤

SpringBoot缩小打包体积的详细步骤

2026年03月21日 Java 我要评论
一、什么是缩小打包体积缩小打包体积是指通过各种优化手段,减少spring boot应用最终部署包(通常是jar文件)的大小。这在微服务架构和云原生部署场景中尤为重要,主要体现在以下几个方面:1.1 核

一、什么是缩小打包体积

缩小打包体积是指通过各种优化手段,减少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>
                <groupid>org.apache.maven.plugins</groupid>
                <artifactid>maven-dependency-plugin</artifactid>
                <version>3.5.0</version>
                <executions>
                    <execution>
                        <id>analyze</id>
                        <goals>
                            <goal>analyze</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

步骤2:排除不必要的依赖

<!-- 排除tomcat(如果使用jetty或undertow) -->
<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>
<!-- 添加轻量级的undertow替代 -->
<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-undertow</artifactid>
</dependency>

2.2 使用spring boot分层jar

步骤3:配置分层jar

<!-- pom.xml - 使用spring boot 2.3+的分层特性 -->
<build>
    <plugins>
        <plugin>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-maven-plugin</artifactid>
            <configuration>
                <layers>
                    <enabled>true</enabled>
                    <configuration>${project.basedir}/layers.xml</configuration>
                </layers>
            </configuration>
        </plugin>
    </plugins>
</build>

创建自定义分层配置 layers.xml

<layers xmlns="http://www.springframework.org/schema/boot/layers"
        xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
        xsi:schemalocation="http://www.springframework.org/schema/boot/layers
                          https://www.springframework.org/schema/boot/layers/layers-2.3.xsd">
    <application>
        <into layer="spring-boot-loader">
            <include>org/springframework/boot/loader/**</include>
        </into>
        <into layer="application" />
    </application>
    <dependencies>
        <into layer="snapshot-dependencies">
            <include>*:*:*snapshot</include>
        </into>
        <into layer="internal-dependencies">
            <include>com.yourcompany:*</include>
        </into>
        <into layer="dependencies" />
    </dependencies>
    <layerorder>
        <layer>dependencies</layer>
        <layer>spring-boot-loader</layer>
        <layer>snapshot-dependencies</layer>
        <layer>internal-dependencies</layer>
        <layer>application</layer>
    </layerorder>
</layers>

2.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 --from=builder --chown=appuser:appuser /app/target/*.jar app.jar
# 提取分层jar
run java -djarmode=layertools -jar app.jar extract
# 复制分层内容
copy --from=builder --chown=appuser:appuser /app/dependencies/ ./
copy --from=builder --chown=appuser:appuser /app/spring-boot-loader/ ./
copy --from=builder --chown=appuser:appuser /app/snapshot-dependencies/ ./
copy --from=builder --chown=appuser:appuser /app/application/ ./
user appuser
# 优化jvm参数
entrypoint ["java", "-xx:+usecontainersupport", "-xx:maxrampercentage=75.0", "-xx:+useg1gc", "-xx:+optimizestringconcat", "-xx:+usestringdeduplication", "org.springframework.boot.loader.jarlauncher"]

2.4 资源文件优化

步骤5:优化静态资源和配置文件

<!-- 在pom.xml中配置资源过滤和压缩 -->
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <excludes>
                <exclude>**/*.psd</exclude>
                <exclude>**/*.ai</exclude>
                <exclude>**/*.xcf</exclude>
            </excludes>
        </resource>
    </resources>
    <plugins>
        <!-- 压缩css/js -->
        <plugin>
            <groupid>com.github.eirslett</groupid>
            <artifactid>frontend-maven-plugin</artifactid>
            <version>1.12.1</version>
            <executions>
                <execution>
                    <id>compress-resources</id>
                    <goals>
                        <goal>yarn</goal>
                    </goals>
                    <configuration>
                        <arguments>build</arguments>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

2.5 自定义classloader和数据压缩

步骤6:实现自定义类加载器

// 自定义类加载器实现懒加载
public class lazyloadingclassloader extends classloader {
    private map<string, 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>
    <groupid>org.graalvm.buildtools</groupid>
    <artifactid>native-maven-plugin</artifactid>
    <version>0.9.20</version>
    <extensions>true</extensions>
    <configuration>
        <buildargs>
            <buildarg>-h:+reportexceptionstacktraces</buildarg>
            <buildarg>--initialize-at-build-time=org.springframework.util.unit.datasize</buildarg>
            <buildarg>--initialize-at-build-time=org.slf4j</buildarg>
        </buildargs>
    </configuration>
    <executions>
        <execution>
            <id>build-native</id>
            <goals>
                <goal>compile-no-fork</goal>
            </goals>
            <phase>package</phase>
        </execution>
    </executions>
</plugin>

2.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.jar=true
# 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 "scale=2; ($(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>
            <groupid>org.springframework.boot.experimental</groupid>
            <artifactid>spring-boot-thin-maven-plugin</artifactid>
            <version>1.0.29.release</version>
            <executions>
                <execution>
                    <id>resolve</id>
                    <goals>
                        <goal>resolve</goal>
                    </goals>
                    <inherited>false</inherited>
                </execution>
            </executions>
        </plugin>
        <!-- 修改默认打包插件 -->
        <plugin>
            <groupid>org.apache.maven.plugins</groupid>
            <artifactid>maven-jar-plugin</artifactid>
            <configuration>
                <archive>
                    <manifest>
                        <mainclass>${start-class}</mainclass>
                    </manifest>
                    <manifestentries>
                        <spring-boot-version>${spring-boot.version}</spring-boot-version>
                        <spring-boot-lib>lib/</spring-boot-lib>
                    </manifestentries>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

2.9 配置排除和瘦身优化

步骤11:完整的pom.xml优化配置

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
         xsi:schemalocation="http://maven.apache.org/pom/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelversion>4.0.0</modelversion>
    <groupid>com.example</groupid>
    <artifactid>slim-app</artifactid>
    <version>1.0.0</version>
    <packaging>jar</packaging>
    <parent>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-parent</artifactid>
        <version>2.7.0</version>
    </parent>
    <properties>
        <java.version>11</java.version>
        <!-- 启用瘦身模式 -->
        <spring-boot.thin.jar>true</spring-boot.thin.jar>
        <!-- 排除devtools -->
        <spring-boot.devtools.exclude>true</spring-boot.devtools.exclude>
    </properties>
    <dependencies>
        <!-- 核心依赖,排除不必要的传递依赖 -->
        <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>
                <exclusion>
                    <groupid>org.hibernate.validator</groupid>
                    <artifactid>hibernate-validator</artifactid>
                </exclusion>
                <exclusion>
                    <groupid>org.springframework</groupid>
                    <artifactid>spring-webmvc</artifactid>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 使用轻量级服务器 -->
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-jetty</artifactid>
        </dependency>
        <!-- 条件化引入依赖 -->
        <dependency>
            <groupid>org.projectlombok</groupid>
            <artifactid>lombok</artifactid>
            <optional>true</optional>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupid>org.springframework.boot</groupid>
                <artifactid>spring-boot-maven-plugin</artifactid>
                <configuration>
                    <!-- 启用分层jar -->
                    <layers>
                        <enabled>true</enabled>
                    </layers>
                    <!-- 排除devtools -->
                    <excludedevtools>true</excludedevtools>
                    <!-- 配置需要排除的依赖 -->
                    <excludes>
                        <exclude>
                            <groupid>org.projectlombok</groupid>
                            <artifactid>lombok</artifactid>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <!-- 依赖分析插件 -->
            <plugin>
                <groupid>org.apache.maven.plugins</groupid>
                <artifactid>maven-dependency-plugin</artifactid>
                <version>3.5.0</version>
                <executions>
                    <execution>
                        <id>analyze-dependencies</id>
                        <goals>
                            <goal>analyze-only</goal>
                        </goals>
                        <configuration>
                            <failonwarning>false</failonwarning>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <!-- 资源优化插件 -->
            <plugin>
                <groupid>org.apache.maven.plugins</groupid>
                <artifactid>maven-resources-plugin</artifactid>
                <version>3.3.1</version>
                <configuration>
                    <encoding>utf-8</encoding>
                    <nonfilteredfileextensions>
                        <nonfilteredfileextension>pdf</nonfilteredfileextension>
                        <nonfilteredfileextension>png</nonfilteredfileextension>
                        <nonfilteredfileextension>jpg</nonfilteredfileextension>
                    </nonfilteredfileextensions>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

三、详细总结

3.1 优化效果对比

优化策略原始体积优化后体积缩减比例适用场景
基础依赖精简80mb60mb25%所有项目
分层jar + 多阶段构建80mb45mb44%容器部署
thin launcher80mb15mb81%微服务
graalvm native80mb25mb69%高性能场景
综合优化80mb18mb78%云原生部署

3.2 最佳实践总结

优先级策略:

  1. 第一优先级(立即实施)
    • 使用spring-boot-maven-plugin的分层jar功能
    • 排除不必要的传递依赖
    • 使用多阶段docker构建
  2. 第二优先级(推荐实施)
    • 替换为轻量级嵌入式服务器(undertow/jetty)
    • 配置资源过滤和排除
    • 使用maven-dependency-plugin分析并移除无用依赖
  3. 第三优先级(可选实施)
    • 采用thin launcher方案
    • 使用graalvm native image
    • 实现自定义类加载器

3.3 关键注意事项

1. 兼容性考量

  • native image对反射、动态代理支持有限
  • thin launcher可能需要调整类加载逻辑
  • 分层jar需要spring boot 2.3+

2. 性能权衡

  • native image启动快但构建慢
  • thin launcher首次启动需要下载依赖
  • 过度精简可能影响功能完整性

3. 监控与维护

  • 建立体积监控基准
  • 在ci/cd流程中自动检查jar大小
  • 定期review依赖使用情况

3.4 实施建议路线图

3.5 最后

缩小spring boot打包体积是一个持续优化的过程,建议:

  1. 从简单开始:先实施基础依赖优化和分层jar
  2. 测量驱动:每次优化前后都要测量体积变化
  3. 平衡取舍:在体积、性能、开发效率之间找到平衡点
  4. 自动化集成:将体积检查集成到ci/cd流程中
  5. 文档记录:记录优化决策和效果,便于团队协作

通过系统性地实施上述优化策略,大多数spring boot应用可以将部署体积缩减50%以上,显著提升部署效率和运行时性能。

以上就是springboot缩小打包体积的详细步骤的详细内容,更多关于springboot缩小打包体积的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com