SpringBoot打包瘦身

起因:使用SpringBoot开发项目,引用了很多依赖,最终打包成可运行的jar文件时,往往有几十M,或者更大,上传服务器要浪费很长时间。

优化方式一

1. 依赖分离

  SpringBoot可运行的jar文件很大是因为,jar文件里包含了很多依赖jar,所以才会生成几十M的文件。

  解决办法是在maven配置中,使用插件:

复制代码
    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <!-- 运行时,读取的lib目录,启动类路径 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <useUniqueVersions>false</useUniqueVersions>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>/data/server/system-demo/libs/</classpathPrefix>
                            <mainClass>com.zh.system.SystemApplication</mainClass>
                        </manifest>
                        <manifestEntries>
                        </manifestEntries>
                    </archive>
                    <!-- 打包时,排除配置文件,配置文件放到jar包同目录的config下 -->
                    <excludes>
                        <!-- 注意,文件路径是按照编译打包后结果目录 -->
                        <exclude>application.yml</exclude>
                    </excludes>
                </configuration>
            </plugin>

            <!-- 打包时,把jar拷贝到指定目录 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>/data/server/system-demo/libs/</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <!-- 跳过单元测试 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>
    </build>
复制代码

  maven-jar-plugin 插件的作用是jar运行时使用的配置,属性包括:classpathPrefix 指定外部jar的路径,mainClass 指定jar包的启动类

  maven-dependency-plugin 插件的作用是打包时,指定依赖jar拷贝的目录。

  /data/server/system-demo 是我准备的项目运行jar包的目录。

  我这里使用的路径都是 /data/server/system-demo/libs/,如果你是在windows系统下编译打包项目,你可以到项目所在的workspace的磁盘根目录下查找,会发现也生成了这样的目录,项目相关的jar包都拷贝到这里了。在服务器上创建目录/data/server/system-demo/libs/,并且把项目需要的jar包都上传到此目录。

 

2. 配置文件管理

  我的项目中的配置文件按服务器环境配置了几套,如下图:

 

  在application.yml的代码,使用这条命令指定加载的子配置文件:spring.profiles.active: test

  这样管理配置很方便,避免多个服务器环境之间的参数切换,带来混淆的问题。但如果你修改代码之后,每个环境都要发布一遍,就会需要修改spring.profiles.active的值后,重复打包的问题。

  所以,按照SpringBoot的运行加载规则,如果在运行jar同一目录有 config 文件夹,会被提前加载的。我们只需要在服务器 /data/server/system-demo/ 下创建一个config文件夹。并只上传此环境的配置文件就好了。

   

3. 总结

  当项目运行时,最终在system-demo目录下,会有2个文件夹,2个文件。

  system-demo-1.0-SNAPSHOT.jar      -------SpringBoot启动jar包

  config    ---------项目的配置文件

  libs      -----------项目的依赖jar

  nohup.out   ------nohup命令运行jar文件之后,生成的临时日志文件

 

 

优化方式二

1. 正常编译JAR包,解压出lib文件夹

  POM文件如下:

复制代码
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId> 
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>com.johnnian.App</mainClass>
                <layout>ZIP</layout>
            </configuration>
            <executions>
            <execution>
                 <goals>
                     <goal>repackage</goal>
                 </goals>
             </execution>
           </executions>
        </plugin>
     <plugins>
<build>
复制代码

  进入项目根目录,执行命令:mvn clean install

  将编译后的Jar包解压,拷贝 BOOT-INF 目录下的lib文件夹 到目标路径;

 

2. 修改pom.xml配置,编译出不带 lib 文件夹的Jar包

复制代码
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId> 
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>com.johnnian.App</mainClass>
                <layout>ZIP</layout>
                <includes> 
                    <include>
                        <groupId>nothing</groupId>
                        <artifactId>nothing</artifactId>
                    </include>  
                </includes>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
     <plugins>
<build>
复制代码

  配置完成后,再次执行编译:mvn clean install

  生成的 Jar 包体积明显变小,外部的 jar 包已经不会被引入了。

 

3. 运行编译后的Jar包

  将 步骤1 解压出来的lib文件夹、步骤2编译的jar包放在同一个目录, 运行下面命令:

java -Dloader.path=/path/to/lib -jar /path/to/springboot-jsp-0.0.1-SNAPSHOT.jar 

  或者在maven中输入一下命令导出需要用到的jar包

mvn dependency:copy-dependencies -DoutputDirectory=F:\ideaWorkPlace\AnalysisEngine\lib  -DincludeScope=runtime

  备注:将/path/to/改成实际的路径。-Dloader.path=lib文件夹路径

  最终目录文件结构是:

├── lib   #lib文件夹
└── springboot-jsp-0.0.1-SNAPSHOT.jar 

  说明:

  1、通常,一个工程项目架构确定后,引入的jar包基本上不会变,改变的大部分是业务逻辑;

  2、后面如果需要变更业务逻辑,只需要轻量地编译工程,大大提高项目部署的效率。

 

posted @   闲人鹤  阅读(1549)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示