给你的 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-INF,META-INF,org 三个部分
打开 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包的管理成本,多人协调开发,构建的时候,还需要专门去关注是否有人更新依赖。
声明: 公众号如需转载该篇文章,发表文章的头部一定要 告知是转至公众号: 后端元宇宙。同时也可以问本人要markdown原稿和原图片。其它情况一律禁止转载!
给你的 SpringBoot 工程部署的 jar 包瘦瘦身吧!的更多相关文章
- 详解docker部署SpringBoot及如何替换jar包
关于docker的安装和使用,可以看看之前这两篇文章.Docker从安装部署到Hello World和Docker容器的使用和连接.这篇文章主要介绍如何在docker上部署springboot项目.关 ...
- java工程打包成jar包,并且解压lib里的jar包
在我们开发完java工程部署时,有时不需要web容器,为了方便部署有时候需要打成jar包. 这里介绍2种Eclipse打jar包的方式, 方式一.工程引用的jar包打在lib目录下 1.工程上右键,E ...
- 转:MAVEN依赖的是本地工程还是仓库JAR包?
相信大家都碰见过 maven 配置的依赖或者是 jar 包或者是工程,在开发的过程当中,我们当然需要引入的是工程,这样查看 maven 依赖的文件的时候,就能直接查看到源码. 一.本地工程依赖 举个例 ...
- Maven依赖的是本地工程还是仓库jar包?
相信大家都碰见过maven配置的依赖或者是jar包或者是工程,在开发的过程当中,我们当然需要引入的是工程,这样查看maven依赖的文件的时候,就能直接查看到源码. 一.本地工程依赖 举个例子,其架构如 ...
- SpringBoot快速引入第三方jar包
工作中,我们常会用到第三方jar包,而这些jar包往往在maven仓库是搜不到的,下面推荐一种简单.快速的引入第三方依赖的方法: 比如第三方jar包在lib文件夹下,对pom.xml的配置如下: &l ...
- 在java工程中导入jar包的注意事项
在java工程中导入jar包后一定要bulid path,不然jar包不可以用.而在java web工程中导入jar包后可以不builld path,但最好builld path.
- maven将自己的springboot项目打包成jar包后,作为工具包引入其他项目,找不到jar中的类
将springboot项目打包成jar包,作为工具包导入项目后,找不到jar中的类. 原因是:springboot项目使用了自动的打包插件. 原先的插件配置: <build> <pl ...
- SpringBoot第一次案例(以及jar包的生成)
一.Springboot简介 Springboot框架就用于简化Spring应用的开发,约定大于配置,去繁从简.从以往的“Spring全家桶时代”正式过渡到”Spring boot,J2EE一站式解决 ...
- springboot服务引入外部jar包在windows运行正常,在linux环境上无法加载到引入jar包的类
一.问题描述 最近开发了一个springboot程序,需要依赖第三方jar包,这个jar包无法直接通过pom远程仓库下载,需要从自己本地引入,于是配置pom文件如下:将本地jar包引入工程,syste ...
- 如何将springboot工程打包成war包并且启动
将项目打成war包,放入tomcat 的webapps目录下面,启动tomcat,即 可访问. 1.pom.xml配置修改 <packaging>jar</packaging> ...
随机推荐
- IntelliJ IDEA上手这一篇就够了,从入门到上瘾
前言 每次换电脑,最最最头疼的事情莫过于安装各种软件和搭建开发环境.这算是不想换电脑的一个原因吧(最主要还是穷).除非是电脑坏了开不了机或者点一下卡一下,真不想换电脑.每次换电脑都得折腾好久. 趁着这 ...
- linux 的 vi 命令详解
vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令.由于对Unix及Linux系统的任何版本,vi编辑器是完全相 ...
- Post-Exploitation Basics
开发后基础知识 https://tryhackme.com/room/postexploit 使用 mimikatz.bloodhound.powerview 和 msfvenom 学习后期开发和维护 ...
- ChatGPT 问答
Win32GUI编程时,创建窗口触发消息的顺序 在Win32 GUI编程中,创建窗口并显示到屏幕上时,系统会触发一系列的消息,这些消息可以用来完成窗口的初始化和其他相关的工作.下面是创建窗口触发消息的 ...
- C#.NET Framework RSA 公钥加密 私钥解密 ver:20230609
C#.NET Framework RSA 公钥加密 私钥解密 ver:20230609 环境说明: .NET Framework 4.6 的控制台程序 . .NET Framework 对于RSA的支 ...
- 混沌演练状态下,如何降低应用的 MTTR(平均恢复时间)
在企业业务领域,锦礼是针对福利.营销.激励等员工采购场景的一站式解决方案,包含面向员工.会员等弹性激励SAAS平台.由于其直接面向公司全体员工,其服务的高可用尤其重要,本文将介绍锦礼商城大促前夕,通过 ...
- 痞子衡嵌入式:主流QuadSPI NOR Flash厂商关于QE位与IO功能复用关联设计
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是几家主流QuadSPI NOR Flash厂商关于QE位与IO功能复用关联设计. 痞子衡之前写过一篇文章 <串行NOR Flash下 ...
- Djiango 创建迁移项报错query = query.decode(errors='replace') AttributeError: 'str' object has no attribute 'decode'
在终端命令行创建迁移项 输入(python manage.py makemigrations) 或(python manage.py migrate)时出现报错信息:Traceback (most r ...
- ZEGO自研RTC+直播系统架构,如何支撑一场高质量直播
近年来得益于网络基础设施的进步,实时音视频(Real-Time Communication,以下简称 RTC)和直播(采用 CDN 进行内容分发)在各行业迅速落地,在疫情的催化下更是推动传统的教育.会 ...
- jdbc-plus是一款基于JdbcTemplate增强工具包,基于JdbcTemplate已实现分页、多租户、动态表名等插件,可与mybatis、mybatis-plus等混合使用
jdbc-plus简介 jdbc-plus是一款基于JdbcTemplate增强工具包,基于JdbcTemplate已实现分页.多租户.动态表名等插件,可与mybatis.mybatis-plus等混 ...