詳解如何給SpringBoot部署的jar包瘦身
一、需求背景
我們知道Spring Boot項(xiàng)目,是可以通過(guò)java -jar 包名 啟動(dòng)的。
那為什么Spring Boot項(xiàng)目可以通過(guò)上述命令啟動(dòng),而其它普通的項(xiàng)目卻不可以呢?
原因在于我們?cè)谕ㄟ^(guò)以下命令打包時(shí)
mvn clean package
一般的maven項(xiàng)目的打包命令,不會(huì)把依賴的jar包也打包進(jìn)去的,所以這樣打出的包一般都很小

但Spring Boot項(xiàng)目的pom.xml文件中一般都會(huì)帶有spring-boot-maven-plugin插件。
該插件的作用就是會(huì)將依賴的jar包全部打包進(jìn)去。該文件包含了所有的依賴和資源文件。
也就會(huì)導(dǎo)致打出來(lái)的包比較大。

打完包就可以通過(guò)java -jar 包名 啟動(dòng),確實(shí)是方便了。
但當(dāng)一個(gè)系統(tǒng)上線運(yùn)行后,肯定會(huì)有需求迭代和Bug修復(fù),那也就免不了進(jìn)行重新打包部署。
我們可以想象一種場(chǎng)景,線上有一個(gè)緊急致命Bug,你也很快定位到了問(wèn)題,就改一行代碼的事情,當(dāng)提交代碼并完成構(gòu)建打包并交付給運(yùn)維。
因?yàn)榇虬膉ar很大,一直處于上傳中.......
如果你是老板肯定會(huì)發(fā)火,就改了一行代碼卻上傳幾百M(fèi)B的文件,難道沒(méi)有辦法優(yōu)化一下嗎?
如今迭代發(fā)布是常有的事情,每次都上傳一個(gè)如此龐大的文件,會(huì)浪費(fèi)很多時(shí)間。
下面就以一個(gè)小項(xiàng)目為例,來(lái)演示如何瘦身。
二、瘦身原理
這里有一個(gè)最基礎(chǔ) SpringBoot 項(xiàng)目,整個(gè)項(xiàng)目代碼就一個(gè)SpringBoot啟動(dòng)類,單是打包出來(lái)的jar就有20多M;
我們通過(guò)解壓命令,看下jar的組成部分。
tar -zxvf spring-boot-maven-slim-1.0.0.jar

我們可以看出,解壓出來(lái)的包有三個(gè)模塊
分為 BOOT-INF,META-INF,org 三個(gè)部分
打開(kāi) BOOT-INF

classes: 當(dāng)前項(xiàng)目編譯好的代碼是放在 classes 里面的,classes 部分是非常小的。
lib: 我們所依賴的 jar 包都是放在 lib 文件夾下,lib部分會(huì)很大。
看了這個(gè)結(jié)構(gòu)我們?cè)撊绾稳ナ萆砟兀?/p>
項(xiàng)目雖然依賴會(huì)很多,但是當(dāng)版本迭代穩(wěn)定之后,依賴基本就不會(huì)再變動(dòng)了。
如果可以把這些不變的依賴提前都放到服務(wù)器上,打包的時(shí)候忽略這些依賴,那么打出來(lái)的Jar包就會(huì)小很多,直接提升發(fā)版效率。
當(dāng)然這樣做你肯定有疑問(wèn)?
既然打包的時(shí)候忽略這些依賴,那通過(guò)java -jar 包名 還可以啟動(dòng)嗎?
這種方式打的包,在項(xiàng)目啟動(dòng)時(shí),需要通過(guò)-Dloader.path指定lib的路徑,就可以正常啟動(dòng)
java -Dloader.path=./lib -jar xxx.jar
三、瘦身實(shí)例演示
1、依賴拆分配置
只需要在項(xiàng)目pom.xml文件中添加下面的配置:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
<layout>ZIP</layout>
<!--這里是填寫需要包含進(jìn)去的jar,
必須項(xiàng)目中的某些模塊,會(huì)經(jīng)常變動(dòng),那么就應(yīng)該將其坐標(biāo)寫進(jìn)來(lái)
如果沒(méi)有則nothing ,表示不打包依賴 -->
<includes>
<include>
<groupId>nothing</groupId>
<artifactId>nothing</artifactId>
</include>
</includes>
</configuration>
</plugin>
<!--拷貝依賴到j(luò)ar外面的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

發(fā)現(xiàn)target目錄中多了個(gè)lib文件夾,里面保存了所有的依賴jar。

自己業(yè)務(wù)相關(guān)的jar也只有小小的168kb,相比之前20.2M,足足小了100多倍;
這種方式打的包,在項(xiàng)目啟動(dòng)時(shí),需要通過(guò)-Dloader.path指定lib的路徑:
java -Dloader.path=./lib -jar spring-boot-maven-slim-1.0.0.jar

雖然這樣打包,三方依賴的大小并沒(méi)有任何的改變,但有個(gè)很大的不同就是我們自己的業(yè)務(wù)包和依賴包分開(kāi)了;
在不改變依賴的情況下,也就只需要第一次上傳lib目錄到服務(wù)器,后續(xù)業(yè)務(wù)的調(diào)整、bug修復(fù),在沒(méi)調(diào)整依賴的情況下,就只需要上傳更新小小的業(yè)務(wù)包即可;
2、自己其它項(xiàng)目的依賴如何處理?
我們?cè)谧鲰?xiàng)目開(kāi)發(fā)時(shí),除了會(huì)引用第三方依賴,也會(huì)依賴自己公司的其它模塊。
比如

這種依賴自己其它項(xiàng)目的工程,也是會(huì)經(jīng)常變動(dòng)的,所以不宜打到外部的lib,不然就會(huì)需要經(jīng)常上傳更新。
那怎么做了?
其實(shí)也很簡(jiǎn)單 只需在上面的插件把你需要打進(jìn)jar的填寫進(jìn)去就可以了
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
<layout>ZIP</layout>
<!--這里是填寫需要包含進(jìn)去的jar,如果沒(méi)有則nothing -->
<includes>
<include>
<groupId>com.jincou</groupId>
<artifactId>xiaoxiao-util</artifactId>
</include>
</includes>
</configuration>
</plugin>這樣只有include中所有添加依賴依然會(huì)打進(jìn)當(dāng)前業(yè)務(wù)包中。
四、總結(jié)
使用瘦身部署,你的業(yè)務(wù)包確實(shí)小了 方便每次的迭代更新,不用每次都上傳一個(gè)很大的 jar 包,從而節(jié)省部署時(shí)間。
但這種方式也有一個(gè)弊端就是增加了Jar包的管理成本,多人協(xié)調(diào)開(kāi)發(fā),構(gòu)建的時(shí)候,還需要專門去關(guān)注是否有人更新依賴。
以上就是詳解如何給SpringBoot部署的jar包瘦身的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot jar包瘦身的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- springboot項(xiàng)目(jar包)指定配置文件啟動(dòng)圖文教程
- SpringBoot中讀取jar包中的resources目錄下的文件的三種方式
- SpringBoot分離打Jar包的兩種配置方式
- SpringBoot項(xiàng)目中jar發(fā)布獲取jar包所在目錄路徑的最佳方法
- springboot通過(guò)jar包啟動(dòng)中文日志亂碼問(wèn)題及解決
- springboot項(xiàng)目打包成jar包的圖文教程
- SpringBoot項(xiàng)目引入第三方sdk?jar包的解決方案
- Spring?Boot項(xiàng)目Jar包加密實(shí)戰(zhàn)教程
相關(guān)文章
mybatis update set 多個(gè)字段實(shí)例
這篇文章主要介紹了mybatis update set 多個(gè)字段實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01
IDEA使用JDBC導(dǎo)入配置jar包連接MySQL數(shù)據(jù)庫(kù)
這篇文章介紹了IDEA使用JDBC安裝配置jar包連接MySQL數(shù)據(jù)庫(kù)的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-12-12
Java文件讀取寫入后 md5值不變的實(shí)現(xiàn)方法
Spring?Boot應(yīng)用程序中如何使用Keycloak詳解
判斷以逗號(hào)分隔的字符串中是否包含某個(gè)數(shù)的實(shí)例

