spring-boot-thin-launcher插件分離jar包的依賴(lài)和配置方式
spring-boot-thin-launcher插件分離jar包的依賴(lài)和配置
Spring Boot項(xiàng)目可以通過(guò)spring-boot-maven-plugin插件打包生成一個(gè)可執(zhí)行的jar包,這樣可以脫離web容器(例如tomcat)直接運(yùn)行。
但默認(rèn)情況下spring-boot-maven-plugin打出來(lái)的包是一個(gè)fat jar,即將所有的依賴(lài)全部打進(jìn)了jar包當(dāng)中,這樣的jar包體積很大,每次更新系統(tǒng)的時(shí)候都需要完整替換整個(gè)jar包(本地還好,如果是云服務(wù)器,網(wǎng)速慢了每次上傳文件都想砸電腦π__π)。
此外,系統(tǒng)切換環(huán)境時(shí),也同時(shí)需要切換配置參數(shù),雖然可以使用配置中心或者利用命令行參數(shù)修改配置,但有時(shí)候也免不了直接需要修改配置文件,這樣的話(huà)就有必要將配置文件從jar包中分離出來(lái),單獨(dú)存放。
Spring社區(qū)大概也考慮到了部分開(kāi)發(fā)者有這樣的需求,所以提供了spring-boot-thin-launcher這個(gè)插件用來(lái)將項(xiàng)目的依賴(lài)和配置從jar包中分離出去。
這個(gè)插件雖然是放到spring-projects-experimental(意思就是實(shí)驗(yàn)性質(zhì)的項(xiàng)目)當(dāng)中的,但從我使用的經(jīng)驗(yàn)來(lái)看應(yīng)該是比較穩(wěn)定的,能夠滿(mǎn)足絕大部分場(chǎng)景的需求。
廢話(huà)少說(shuō),還是先上代碼吧
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<!--項(xiàng)目的執(zhí)行入口-->
<mainClass>com.example.Application</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>1.0.12.RELEASE</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-maven-plugin</artifactId>
<version>1.0.12.RELEASE</version>
<executions>
<execution>
<!--在編譯時(shí)下載依賴(lài)包 -->
<id>resolve</id>
<goals>
<goal>resolve</goal>
</goals>
<inherited>false</inherited>
</execution>
</executions>
</plugin>
<!--移動(dòng)配置文件到外部文件夾-->
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<move file="${project.build.directory}/classes/application.yml" todir="${project.build.directory}/thin/root/config"/>
<copy todir="${project.build.directory}/thin/root/">
<fileset dir="${basedir}/bin"/>
</copy>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>在maven-antrun-plugin中可以根據(jù)需要定義一些額外的任務(wù),比如移動(dòng)其它的配置文件,或者將外部的一些文件加入到項(xiàng)目目錄中(比如執(zhí)行腳本等)。
這樣配置后,
打包以后的target目錄大概是這樣的

其中thin目錄下面就可以作為整個(gè)項(xiàng)目的部署目錄了,config是配置文件的存放目錄,respository下面是所有的依賴(lài)包,backend-2.0.jar中僅包含了項(xiàng)目自身的資源,體積比之前小太多了。
##運(yùn)行原理那為什么執(zhí)行時(shí),系統(tǒng)知道自動(dòng)去外部加載依賴(lài)和配置呢?
這個(gè)問(wèn)題需要首先了解打包后的結(jié)構(gòu),把backend-2.0.jar解壓之后,會(huì)發(fā)現(xiàn)除了我們自己的類(lèi)和資源以外,還多了一個(gè)類(lèi):org.springframework.boot.loader.wrapper.ThinJarWrapper,其實(shí)我們?cè)谶\(yùn)行項(xiàng)目時(shí),這個(gè)類(lèi)才是真正的項(xiàng)目入口,它會(huì)在默認(rèn)位置查找項(xiàng)目相關(guān)的依賴(lài),如果沒(méi)有找到,甚至還會(huì)從指定的maven倉(cāng)庫(kù)中直接下載,所以啟動(dòng)時(shí)系統(tǒng)能夠識(shí)別到外部的依賴(lài)包。
至于外部配置,是因?yàn)镾pring Boot框架在讀取配置文件時(shí),會(huì)默認(rèn)讀取幾個(gè)目錄下的配置文件,其中優(yōu)先級(jí)最高的就是當(dāng)前目錄下的config目錄(所以config目錄的名字不能改成其它的)。
執(zhí)行jar包的時(shí)候需要注意,要額外添加一個(gè)參數(shù)來(lái)指定依賴(lài)包所在的倉(cāng)庫(kù)位置(在我們的配置中就在jar包的當(dāng)前文件夾)
例如:-Dthin.root=. 默認(rèn)的位置是${user.home}/.m2,如果倉(cāng)庫(kù)中沒(méi)有需要的依賴(lài),啟動(dòng)jar包時(shí)還會(huì)自動(dòng)連接遠(yuǎn)程倉(cāng)庫(kù)進(jìn)行下載,導(dǎo)致啟動(dòng)時(shí)間非常長(zhǎng),這一點(diǎn)需要注意。
spring-boot-thin-launcher還有很多可配置的參數(shù),具體可以到 官網(wǎng) 上自行查看。
附上一個(gè)通用的spring-boot-thin-launcher打包文件的啟動(dòng)腳本
#!/bin/bash
#這里指定需要運(yùn)行的jar包的名字
APP_NAME="your-jar-name.jar"
JVM_ARGS="-Xms512M -Xmx2048M -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/log/heap.hprof"
THIN_ARGS="-Dthin.root=. -Dthin.offline=true"
#使用說(shuō)明,用來(lái)提示輸入?yún)?shù)
usage() {
echo "Usage: sh 執(zhí)行腳本.sh [start|stop|restart|status|run]"
exit 1
}
#檢查程序是否在運(yùn)行
is_exist(){
pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}' `
#如果不存在返回1,存在返回0
if [ -z "${pid}" ]; then
return 1
else
return 0
fi
}
#后臺(tái)啟動(dòng)
start(){
is_exist
if [ $? -eq "0" ]; then
echo "${APP_NAME} is already running. pid=${pid} ."
else
echo "${APP_NAME} running with args: nohup java $THIN_ARGS -jar $JVM_ARGS $APP_NAME "
nohup java $THIN_ARGS -jar $JVM_ARGS $APP_NAME >> catalina.out 2>&1 &
fi
}
#前臺(tái)啟動(dòng)
run(){
is_exist
if [ $? -eq "0" ]; then
echo "${APP_NAME} is already running. pid=${pid} ."
else
echo "${APP_NAME} running with args: java $THIN_ARGS -jar $JVM_ARGS $APP_NAME"
java $THIN_ARGS -jar $JVM_ARGS $APP_NAME
fi
}
#停止方法
stop(){
is_exist
if [ $? -eq "0" ]; then
kill -9 $pid
else
echo "${APP_NAME} is not running"
fi
}
#輸出運(yùn)行狀態(tài)
status(){
is_exist
if [ $? -eq "0" ]; then
echo "${APP_NAME} is running. Pid is ${pid}"
else
echo "${APP_NAME} is NOT running."
fi
}
#重啟
restart(){
stop
start
}
#根據(jù)輸入?yún)?shù),選擇執(zhí)行對(duì)應(yīng)方法,不輸入則執(zhí)行使用說(shuō)明
case "$1" in
"start")
start
;;
"run")
run
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
*)
usage
;;
esac總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
mybatis xml注釋sql的注意事項(xiàng)及說(shuō)明
這篇文章主要介紹了mybatis xml注釋sql的注意事項(xiàng)及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
使用FeignClient進(jìn)行微服務(wù)交互方式(微服務(wù)接口互相調(diào)用)
這篇文章主要介紹了使用FeignClient進(jìn)行微服務(wù)交互方式(微服務(wù)接口互相調(diào)用),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
深入講解spring boot中servlet的啟動(dòng)過(guò)程與原理
這篇文章主要給大家介紹了關(guān)于spring boot中servlet啟動(dòng)過(guò)程與原理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07
解析MapStruct轉(zhuǎn)換javaBean時(shí)出現(xiàn)的詭異事件
在項(xiàng)目中用到了MapStruct,對(duì)其可以轉(zhuǎn)換JavaBean特別好奇,今天小編給大家分享一個(gè)demo給大家講解MapStruct轉(zhuǎn)換javaBean時(shí)出現(xiàn)的詭異事件,感興趣的朋友一起看看吧2021-09-09
java gui詳解貪吃蛇小游戲?qū)崿F(xiàn)流程
剛開(kāi)始學(xué)JAVA GUI,就練手寫(xiě)了一個(gè)小時(shí)候經(jīng)常在諾基亞上玩的一個(gè)小游戲__貪吃蛇.做的比較簡(jiǎn)單,但還是可以玩的.感興趣的朋友快來(lái)看看吧2021-11-11
java實(shí)現(xiàn)爬蟲(chóng)爬網(wǎng)站圖片的實(shí)例代碼
這篇文章主要介紹了java實(shí)現(xiàn)爬蟲(chóng)爬網(wǎng)站圖片的實(shí)例代碼,需要的朋友可以參考下2018-06-06

