公司的這種打包啟動方式,我簡直驚呆了
theme: cyanosis
前言
大家都知道,SpringBoot應用最終會打出一個Fat Jar
, 裡面包含了用到的全部依賴,啟動也非常簡單,java -jar xxx.jar
即可。
但是我們公司打出的最終包,將依賴包挪到了外部,然後啟動的時候通過loader.path
指定依賴包的位置,如java -Dloader.path=libs -jar xxxx
的方式啟動,也能夠啟動成功。
這樣做最大的一個好處就是如果發現某個依賴出現問題,那麼我只需要在libs替換其中某個依賴,影響範圍可以減小很多。
那大家是不是很好奇是怎麼做到的呢?
打包方式詳解
主要是通過兩個maven外掛打出這樣的結構的包。
- spring-boot-maven-plugin
該外掛是spring boot
官方提供的一個打包外掛,主要用來打出fat jar
,並且提供了支援java -jar xxx.jar
方式啟動。 官網地址:https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/htmlsingle/。
我們需要用這個外掛,因為只有它可以打出支援啟動的jar,但是打出的包中又不能有依賴,該怎麼做呢?如下圖:
layout
: 佈局方式,這裡要選擇ZIP
,後面說明原因。-
includes
: 選擇包含哪些依賴,這裡寫了一個不存在的jar,那麼也間接實現了不打入其他的依賴。這種方式比較ugly,但是目前沒有找到更加合適的方案。 -
maven-assembly-plugin
maven-assembly-plugin外掛可以靈活定製打包內容,官網地址:https://maven.apache.org/plugins/maven-assembly-plugin/。
我們現在就是想辦法利用該外掛抽出我們用到的依賴包,該怎麼做呢?
我們現在看下assembly.xml
中的關鍵配置:
- 可以根據
include
、exclude
屬性通過正則靈活的抽取相關依賴到指定的目錄下
最終執行mvn clean package
在target目錄下得到最終的安裝包:
解壓該安裝包:
開啟libs目錄:
啟動方式解析
現在我們已經按照自己想要的結構打出包了,那如何在啟動的時候載入libs
目錄中的依賴呢?
前面提到了springboot
外掛打出的包是啟動的入口,實際上在這個包裡面springboot
會自動打入一個引導類org.springframework.boot.loader.Launcher
,它是 Spring Boot
可執行 jar 的主要入口點,它是 Spring Boot jar
檔案中的實際 Main-Class
,用於設定適當的 URLClassLoader
並最終呼叫Spring Boot
專案中定義的 main()
方法。
Launcher
有三個子類(JarLauncher
、WarLauncher
和 PropertiesLauncher
),如果我們打包外掛的layout
配置的是ZIP
的方式,它會使用PropertiesLauncher
。
PropertiesLauncher機制說明:
預設情況下,PropertiesLauncher
在 BOOT-INF/lib/
中載入,我們可以通過設定loader.properties
中的loader.path
或 LOADER_PATH
環境變數來增加其它的載入位置。
loader.path
:配置逗號分隔的Classpath
類路徑,例如lib,${HOME}/app/lib
,前面的路徑優先,類似於 javac 命令中的-classpath
。loader.home
:用於解析loader.path
配置的相對路徑,預設是${user.dir}
。
所以,打包成功後,我們可以通過java -jar -Dloader.path=xx1,xx2,public <jarName>.jar
命令來啟動程式,這樣對應目錄下的依賴均會被載入。
總結
這種打包啟動方式雖然不常見,但是還是有一定的價值的,特別是在專案元件模組比較多的時候,出現緊急缺陷,可以按需替換包,將影響範圍控制到最小。
如果本文對你有幫助,請隨手留下一個贊吧。
本文正在參加「金石計劃 . 瓜分6萬現金大獎」
- Java7到Java17, Switch語句進化史
- 樂觀鎖思想在JAVA中的實現——CAS
- 一步步帶你設計MySQL索引資料結構
- 我總結了寫出高質量程式碼的12條建議
- 工作這麼多年,我總結的資料傳輸物件 (DTO) 的最佳實踐
- Spring專案中用了這種解耦模式,經理對我刮目相看
- 大資料HDFS憑啥能存下百億資料?
- 5個介面效能提升的通用技巧
- 你的哪些SQL慢?看看MySQL慢查詢日誌吧
- 90%的Java開發人員都會犯的5個錯誤
- 喪心病狂,竟有Thread.sleep(0)這種寫法?
- 為什麼更推薦使用組合而非繼承關係?
- 一個30歲程式設計師的覺醒和進擊
- 推薦8個提高工作效率的IntelliJ外掛
- 公司的這種打包啟動方式,我簡直驚呆了
- 告別醜陋判空,一個Optional類搞定
- 你不知道的Map家族中的那些冷門容器
- SpringBoot 2.x整合Log4j2日誌
- SpringBoot應用自定義logback日誌
- 你確定懂了Java中的序列化機制嗎