使用springboot 打包插件去除jar包瘦身
1、pom文件配置
1.1 添加maven-dependency-plugin插件用于將引用的jar包拷貝到指定的路徑
便于后續(xù)tomcat啟動指定依賴包路徑
<!--拷貝依賴到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>
使用這個插件構(gòu)建完之后的目錄結(jié)構(gòu)多了一個lib目錄(即上述配置的outputDirectory指定的路徑),里面是依賴的jar包:
1.2 springboot項目使用spring-boot-maven-plugin打包插件
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <executable>true</executable> <layout>ZIP</layout> <mainClass> com.iasp.BasicStarter </mainClass> <!--只包含自己--> <includes> <include> <groupId>${groupId}</groupId> <artifactId>${artifactId}</artifactId> </include> <!--或者--> <!--依賴jar不打進(jìn)項目jar包中--> <!--<include> <groupId>nothing</groupId> <artifactId>nothing</artifactId> </include>--> </includes> <!--不包含哪些--> <!--<excludeGroupIds>--> <!--com.hundsun.jrescloud,--> <!--org.springframework.boot,--> <!--org.springframework--> <!--</excludeGroupIds>--> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin>
配置上述打包之后就會排除相應(yīng)的jar包,使得由插件打成的Flat jar包大小變小,便于上傳服務(wù)器發(fā)布,效果如下,BOOT-INF目錄下的lib目錄沒有了:
原先打成的jar包里的結(jié)構(gòu)為
然后在啟動項目時指定jar包路徑-Dloader.path="../lib",這樣就可以達(dá)到瘦身效果了,其中依賴放在D:develop/shared/fjar目錄下,執(zhí)行運行命令
java -Dloader.path="D:develop/shared/fjar" -jar mytest.jar
附注:另外一種啟動方案是可以不加-Dloader.path="D:develop/shared/fjar"來指定路徑,直接使用如下指令啟動
java -jar mytest.jar
使用上述啟動的話需要添加maven-jar-plugin插件,配置<classpathPrefix>屬性,另外在處理一些讀取可執(zhí)行jar中的文件時,可以使用maven-jar-plugin插件替換spring-boot-maven-plugin進(jìn)行打包操作
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <!--addClasspath表示需要加入到類構(gòu)建路徑--> <addClasspath>true</addClasspath> <!--classpathPrefix指定生成的Manifest文件中Class-Path依賴lib前面都加上路徑,構(gòu)建出lib/xx.jar--> <classpathPrefix>lib/</classpathPrefix> <mainClass>com.common.util.CommonUtilsApplication</mainClass> </manifest> </archive> </configuration> </plugin>
上述插件效果就是在打成的包里META_INF目錄下的MANIFEST.MF文件里增加Class-path對應(yīng)jar,這樣在后面應(yīng)用剛啟動時就會根據(jù)Class-Path的只去加載需要的版本依賴(解決在共享目錄里存在多版本加載引用沖突問題),這個效果就等效加參數(shù)-classpath xxx(具體的jar)。
此時就是將需要的jar目錄lib放在和要運行的xxx.jar同級目錄即可,啟動時就可以不加-Dloader.path參數(shù)了,如果lib目錄和要運行的xxx.jar不在同級目錄的話,則需要使用-Dloader.path來啟動
如下:在同一級目錄啟動
不在同一級目錄啟動:
其中-Dloader.path可以指定多個目錄,這樣在存在多個微服務(wù)情況下可將一些公共用到的jar放在一個共享目錄中,每個微服務(wù)獨有的jar可以放在微服務(wù)私有的目錄下(解決jar版本沖突問題),示例如下:
注意:
1、使用-Dloader.path需要在打包的時候增加<layout>ZIP</layout>,不指定的話-Dloader.path不生效
對于多個微服務(wù)瘦身打包建議使用maven-jar-plugin打包,避免因為spring-boot-maven-plugin打包機(jī)制導(dǎo)致的一些應(yīng)用啟動問題(已踩坑)
2、若存在不同版本依賴:
比如項目A依賴Y庫的1.0版本,項目B依賴Y庫的2.0版本,那么可能會出現(xiàn)版本依賴沖突(兩個版本不兼容的情況下),解決方案:
2.1、能做到版本一致就保持使用同一個版本,保證版本一致??梢允褂胢aven的版本依賴管理進(jìn)行處理,即在父pom文件使用<dependencyManagement>統(tǒng)一管理依賴版本
2.2、讓項目各自依賴所需的版本并打進(jìn)war包中,把其他同版本的jar包放在同一個共享包下
測試發(fā)現(xiàn)依賴在查找時從上往下找,匹配到就用第一個,如下圖會使用comm-0.0.1.jar版本的
附注:
使用spring-boot-maven-plugin插件,會將依賴的jar包全部打包進(jìn)去,這樣就可以直接運行生成的 JAR 包,簡化了我們開發(fā)操作。
使用spring-boot-maven-plugin插件如果不指定程序主運行入口類的話默認(rèn)為Main-Class: org.springframework.boot.loader.JarLauncher
這個可以自定義執(zhí)行主入口類,有以下幾種方式:
1.POM繼承spring-boot-starter-parent
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <!-- The main class to start by executing java -jar --> <start-class>ccom.notes.JavaNotesApplication</start-class> </properties>
2.POM不是繼承spring-boot-starter-parent時需指定
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.1.9.RELEASE</version> <configuration> <mainClass>com.notes.JavaNotesApplication</mainClass> <layout>ZIP</layout> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin>
3.POM不是繼承spring-boot-starter-paren,且使用maven-jar-plugin插件來指定執(zhí)行的類
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <useUniqueVersions>false</useUniqueVersions> <classpathPrefix>lib/</classpathPrefix> <mainClass>com.notes.JavaNotesApplication</mainClass> </manifest> <manifestEntries> <version>${project.version}</version> </manifestEntries> </archive> </configuration> </plugin>
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java獲取系統(tǒng)路徑字體、得到某個目錄下的所有文件名、獲取當(dāng)前路徑
這篇文章主要介紹了java獲取系統(tǒng)路徑字體、得到某個目錄下的所有文件名、獲取當(dāng)前路徑,需要的朋友可以參考下2014-04-04Spring Mybatis Mapper模糊查詢的幾種方法
在Spring結(jié)合Mybatis進(jìn)行開發(fā)時,實現(xiàn)模糊查詢是一個常見需求,在Mybatis中,LIKE查詢可以通過多種方式實現(xiàn),本文給大家介紹了Spring Mybatis Mapper模糊查詢的幾種方法,需要的朋友可以參考下2024-03-03Spring 處理 HTTP 請求參數(shù)注解的操作方法
這篇文章主要介紹了Spring 處理 HTTP 請求參數(shù)注解的操作方法,本文通過實例代碼給大家介紹的非常詳細(xì),感興趣的朋友參考下吧2024-04-04java中SynchronizedList和Vector的區(qū)別詳解
這篇文章主要介紹了java中SynchronizedList和Vector的區(qū)別詳解,Vector是java.util包中的一個類。 SynchronizedList是java.util.Collections中的一個靜態(tài)內(nèi)部類。,需要的朋友可以參考下2019-06-06Java編程實現(xiàn)時間和時間戳相互轉(zhuǎn)換實例
這篇文章主要介紹了什么是時間戳,以及Java編程實現(xiàn)時間和時間戳相互轉(zhuǎn)換實例,具有一定的參考價值,需要的朋友可以了解下。2017-09-09SparkSQL中的JSON內(nèi)置函數(shù)全解析
你是否曾經(jīng)為處理JSON數(shù)據(jù)而頭疼?SparkSQL為我們提供了強(qiáng)大的內(nèi)置JSON函數(shù),讓JSON處理變得輕而易舉,本文將帶你深入了解這些函數(shù),感興趣的朋友一起看看吧2024-08-08