springboot打包瘦身

项目场景:

开发中往往会面临本地开发远程部署的尴尬境地,尤其是面对向日葵等远程桌面软件的时候,龟速的上传速度,往往出现修改bug1分钟,上传代码十分钟的尴尬境地,尤其是面对多模块的情况下,更是修改1分钟上传一小时的离谱状况,因此为了缩短上传时间,最简单的方案,就是缩小jar包的体积。


问题描述

我们从互联网上拉取一个若依或者pigx的框架,在没有开发的情况下,会发现包的体积已经来到了百兆,随着业务逻辑的增加,引用的包越来越多,会发现这个jar包的体积会越来越不可控,因为,缩小包的体积就成了重中之重。

原因分析:

首先要先分析为什么springboot的包为什么会这么大,也就是springboot的打包机制
Spring Boot应用打包机制充分利用了Maven或Gradle构建工具的强大功能,旨在简化传统Java应用的构建与部署流程。其核心在于创建一个可执行的Fat JAR,使得开发者能够轻松地将整个Spring Boot应用及其依赖项打包成单个文件,从而实现一键启动和便捷部署。

对于使用Maven构建的Spring Boot应用,spring-boot-maven-plugin是关键插件,负责处理Fat JAR的构建。在pom.xml文件中,通常会看到如下配置:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring-boot.version}</version>
            <configuration>
                <!-- 可选配置项,如mainClass属性指定入口类 -->
                <mainClass>${start-class}</mainClass>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

通过mvn package命令,Maven首先会按照标准流程构建项目,随后spring-boot-maven-plugin会执行repackage目标,该目标会重新包装已生成的标准JAR文件,将其转换为包含所有依赖项和适当的启动器信息的Fat JAR。这样生成的JAR可以直接通过java -jar命令启动。

Spring Boot应用打包机制均确保了生成的包不仅包含了项目本身的类,还包含了运行时所必需的所有依赖库,以及一些特定的元数据(如MANIFEST.MF中的启动类信息)。这一特性大大简化了部署过程,并有助于提升应用的可移植性和维护性。Fat jar中的内容:
在这里插入图片描述
META-INF/: 包含MANIFEST.MF文件和其他元数据信息,其中Main-Class属性指向Spring Boot的启动类加载器。
BOOT-INF/classes/: 存放项目自身的类文件和资源文件。
BOOT-INF/lib/: 放置所有依赖的jar包,包括Spring Boot starter依赖以及其他第三方库。(如果项目中有静态资源文件,也会在BOOT-INF下有对应的static、templates等目录)

当我们解压jar包之后,去看lib包,也就是依赖包的体积的时候,赫然发现他的体积竟然占到了整个jar包体积的百分之九十五以上。
对于经常部署的同学们来说,配置文件可以外挂,那么这些依赖是否也可以进行外挂呢,一般当我们版本稳定之后才会去进行部署,因此依赖可以视为几乎不会动的存在,所以我们是否可以把依赖从包里面剥离呢。
理论成立,接下来就是行动了。

解决方案:

既然程序是基于maven进行打包构建的,也因此定然是修改maven的构建文件。
做出如下修改
需要注意的是启动类一定要修改成自己的启动类地址,不要采用这里的启动类,否则会出现启动失败的情况
修改前

<plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>

修改后

  <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <!--启动类配置-->
                    <mainClass>com.pig4cloud.pigx.PigxAdminApplication</mainClass>
                    <!--解决windows命令行窗口中文乱码-->
                    <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
                    <layout>ZIP</layout>
                    <!--配置需要打包进项目的jar-->
                    <includes>
                        <!--这里是填写需要包含进去的jar,
                        	必须项目中的某些模块,会经常变动,那么就应该将其坐标写进来
                        	如果没有则non-exists ,表示不打包依赖
                        -->
                        <include>
                            <groupId>non-exists</groupId>
                            <artifactId>non-exists</artifactId>
                        </include>
                    </includes>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
                            <!--是否排除传递性-->
                            <excludeTransitive>false</excludeTransitive>
                            <!--是否去掉 jar 包版本信息-->
                            <stripVersion>false</stripVersion>
                            <!--包含范围-->
                            <includeScope>runtime</includeScope>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>

增加上面的配置项之后会发现,此时打好的包就已经很小了,大概缩小比例可以达到100倍以上,正常的构建是不会存在lib这个包的,修改之后会多出来一个lib包,这个lib包里面就是所有的依赖。
在这里插入图片描述
到现在为止我们的依赖就已经成功剥离了,但是仅仅是剥离是不够的,我们是无法正常启动的,此时我们需要往java -jar启动命令里增加-Dloader.path=“./lib”
完整命令如下

java -jar -Dloader.path="./lib" javaFileName.jar

这里的jar包名称替换成自己的jar包名称,此时即可看到启动成功。
这里只讲述了jar包的启动方法,docker部署与这个相同,只需要往docker的启动命令里增加这一项即可,需要注意的是我这里的path因为lib和jar包为同级,因此写的是./lib ,如果不为同级,需要根据自己的情况调整路径。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值