给你的 SpringBoot 工程部署的 jar 包瘦瘦身吧!

之前有写过一篇有关maven插件的文章

spring-boot-maven-plugin插件详解

一、需求背景

我们知道Spring Boot项目,是可以通过java -jar 包名 启动的。

那为什么Spring Boot项目可以通过上述命令启动,而其它普通的项目却不可以呢?

原因在于我们在通过以下命令打包时

mvn clean package

一般的maven项目的打包命令,不会把依赖的jar包也打包进去的,所以这样打出的包一般都很小

但Spring Boot项目的pom.xml文件中一般都会带有spring-boot-maven-plugin插件。

该插件的作用就是会将依赖的jar包全部打包进去。该文件包含了所有的依赖和资源文件。

也就会导致打出来的包比较大。

打完包就可以通过java -jar 包名 启动,确实是方便了。

但当一个系统上线运行后,肯定会有需求迭代和Bug修复,那也就免不了进行重新打包部署。

我们可以想象一种场景,线上有一个紧急致命Bug,你也很快定位到了问题,就改一行代码的事情,当提交代码并完成构建打包并交付给运维。

因为打包的jar很大,一直处于上传中.......

如果你是老板肯定会发火,就改了一行代码却上传几百MB的文件,难道没有办法优化一下吗?

如今迭代发布时常有的事情,每次都上传一个如此庞大的文件,会浪费很多时间。

下面就以一个小项目为例,来演示如何瘦身。

二、瘦身原理

这里有一个最基础 SpringBoot 项目,整个项目代码就一个SpringBoot启动类,但是打包出来的jar就有20多M;

我们通过解压命令,看下jar的组成部分。

tar -zxvf spring-boot-maven-slim-1.0.0.jar

我们可以看出,解压出来的包有三个模块

分为 BOOT-INFMETA-INForg 三个部分

打开 BOOT-INF

classes: 当前项目编译好的代码是放在 classes 里面的,classes 部分是非常小的。

lib: 我们所依赖的 jar 包都是放在 lib 文件夹下,lib部分会很大。

看了这个结构我们该如何去瘦身呢?

项目虽然依赖会很多,但是当版本迭代稳定之后,依赖基本就不会再变动了。

如果可以把这些不变的依赖提前都放到服务器上,打包的时候忽略这些依赖,那么打出来的Jar包就会小很多,直接提升发版效率。

当然这样做你肯定有疑问?

既然打包的时候忽略这些依赖,那通过java -jar 包名 还可以启动吗?

这种方式打的包,在项目启动时,需要通过-Dloader.path指定lib的路径,就可以正常启动

java -Dloader.path=./lib -jar xxx.jar

三、瘦身实例演示

1、依赖拆分配置

只需要在项目pom.xml文件中添加下面的配置:

 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
     <executable>true</executable>
     <layout>ZIP</layout>
     <!--这里是填写需要包含进去的jar,
          必须项目中的某些模块,会经常变动,那么就应该将其坐标写进来
          如果没有则nothing ,表示不打包依赖 -->

     <includes>
      <include>
       <groupId>nothing</groupId>
       <artifactId>nothing</artifactId>
      </include>
     </includes>
    </configuration>
   </plugin>

   <!--拷贝依赖到jar外面的lib目录-->
   <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>
        ${project.build.directory}/lib
       </outputDirectory>
      </configuration>
     </execution>
    </executions>
   </plugin>
  </plugins>
 </build>

再次打包

mvn clean package

发现target目录中多了个lib文件夹,里面保存了所有的依赖jar。

自己业务相关的jar也只有小小的168kb,相比之前20.2M,足足小了100多倍;

这种方式打的包,在项目启动时,需要通过-Dloader.path指定lib的路径:

java -Dloader.path=./lib -jar spring-boot-maven-slim-1.0.0.jar

虽然这样打包,三方依赖的大小并没有任何的改变,但有个很大的不同就是我们自己的业务包依赖包分开了;

在不改变依赖的情况下,也就只需要第一次上传lib目录到服务器,后续业务的调整、bug修复,在没调整依赖的情况下,就只需要上传更新小小的业务包即可;

2、自己其它项目的依赖如何处理?

我们在做项目开发时,除了会引用第三方依赖,也会依赖自己公司的其它模块。

比如

这种依赖自己其它项目的工程,也是会经常变动的,所以不宜打到外部的lib,不然就会需要经常上传更新。

那怎么做了?

其实也很简单 只需在上面的插件把你需要打进jar的填写进去就可以了

<plugin>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-maven-plugin</artifactId>
 <configuration>
  <executable>true</executable>
  <layout>ZIP</layout>
  <!--这里是填写需要包含进去的jar,如果没有则nothing -->
   <includes>
    <include>
     <groupId>com.jincou</groupId>
     <artifactId>xiaoxiao-util</artifactId>
    </include>
   </includes>
 </configuration>
</plugin>

这样只有include中所有添加依赖依然会打进当前业务包中。

四、总结

使用瘦身部署,你的业务包确实小了 方便每次的迭代更新,不用每次都上传一个很大的 jar 包,从而节省部署时间。

但这种方式也有一个弊端就是增加了Jar包的管理成本,多人协调开发,构建的时候,还需要专门去关注是否有人更新依赖。

求一键三连:点赞、转发、在看。

相关推荐

  • 【进阶玩法】策略+责任链+组合实现合同签章
  • 一个Demo搞定前后端大文件分片上传、断点续传、秒传
  • 重磅!西工大李学龙团队研发大模型自主无人机集群!
  • 8年干出千亿市值,东南亚最大快递IPO了
  • 李克强:大力发展新一代信息技术、人工智能、数字经济等(2020 年 1 月)
  • 再看大模型微调数据质量如何评估:已有方法回顾及IFD指令遵循难度筛选的思路与聚类细节
  • Python制作进度条,原来有这么多方法
  • 顶级ML后端工程师“进化”指南
  • Instagram 仅 3 名工程师,如何做到 1400 万用户?
  • 第五要素|大模型时代,数据治理与AI相互依存形成闭环
  • 纵腾湖仓全链路落地实践
  • Midjourney重大升级,网页版正式上线!生成图像真实清晰
  • 港大等发布GraphGPT:1/50微调参数,准确率提升10倍!无需超长token,LLM也能读懂图结构
  • 陶哲轩论文漏洞竟被AI发现,26年预言要成真!看定理名猜出研究方向,大神直呼AI能力惊人
  • 中美程序员不完全对比,太真实了。。。
  • 生成的分子几乎 100% 有效,用于逆向分子设计的引导扩散模型
  • 小模型如何比肩大模型,北理工发布明德大模型MindLLM,小模型潜力巨大
  • 多模态搜索算法如何让视频搜索更精准?腾讯独家揭秘,超详细
  • 谷歌20亿美元砸向Anthropic:大模型军备竞赛升级
  • 国内唯一全面对标OpenAI的创业公司,大模型已经出到第三代