搞了一個(gè)迭代發(fā)布下SpringBoot Jar瘦身方案,老大給我打了個(gè)A+
下面就以一個(gè)小項(xiàng)目為例,簡述小弟所用的瘦身方案。當(dāng)然如果是內(nèi)網(wǎng)發(fā)布或者你用的寬帶異常給力,瘦身就沒有多大意義了。
項(xiàng)目簡介
新建一個(gè)練習(xí)用的項(xiàng)目,其結(jié)構(gòu)如下
其中ht-ui-web依賴于ht-domain、ht-repository、ht-service,實(shí)現(xiàn)了一個(gè)簡單的GetMapping。
首先我們要對(duì)Jar包有一個(gè)初步認(rèn)識(shí),它的內(nèi)部結(jié)構(gòu)如下
example.jar|+-META-INF| +-MANIFEST.MF+-org| +-springframework| +-boot| +-loader| +-<spring boot loader classes>+-BOOT-INF+-classes| +-mycompany| +-project| +-YourClasses.class+-lib+-dependency1.jar+-dependency2.jar
運(yùn)行該Jar時(shí)默認(rèn)從BOOT-INF/classes加載class,從BOOT-INF/lib加載所依賴的Jar包。如果想要加入外部的依賴Jar,可以通過設(shè)置環(huán)境變量LOADER_PATH來實(shí)現(xiàn)。
如此一來,就可以確認(rèn)我們的思路了:
2. 在啟動(dòng)Jar時(shí),設(shè)置LOADER_PATH使用上一步的libs
這樣,我們最終打包的jar包體積就大大減少,每次迭代后只需要更新這個(gè)精簡版的Jar即可。
打包時(shí)瘦身
通常我們是用spring-boot-maven-plugin進(jìn)行打包,通過閱讀文檔發(fā)現(xiàn)可以通過配置使得該插件在打包時(shí)忽略特定的依賴,文檔在spring-boot-maven-plugin。
首先備份一下原先的依賴:編譯打包成Flat Jar,然后將BOOT-INF/lib下的除去ht-*相關(guān)的jar文件全部解壓出來,另存到libs目錄下。
接著修改pom.xml配置如下
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><layout>ZIP</layout><!--去除在生產(chǎn)環(huán)境中不變的依賴--><excludeGroupIds>org.springframework.boot,org.springframework,org.springframework.data,org.mongodb,com.github.0604hx,com.fasterxml.jackson.core,commons-beanutils,commons-codec,org.apache.commons,org.apache.tomcat.embed,org.hibernate,org.slf4j,com.jayway,org.jboss,com.alibaba,com.fasterxml,commons-collections,ch.qos.logback,org.scala-lang,org.yaml,org.jboss.logging,javax.validation,nz.net.ultraq.thymeleaf,org.thymeleaf,ognl,org.unbescape,org.javassist</excludeGroupIds></configuration></plugin></plugins></build>
此時(shí)打包好的ht-ui-web.jar只有117kb這樣
但是由于沒有其他依賴,ht-ui-web.jar是不能如期運(yùn)行起來的
java -jar ht-ui-web-1.0.jarException in thread "main" java.lang.reflect.InvocationTargetExceptionat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.lang.reflect.Method.invoke(Unknown Source)at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)at org.springframework.boot.loader.PropertiesLauncher.main(PropertiesLauncher.java:521)Caused by: java.lang.NoClassDefFoundError: org/springframework/boot/SpringApplicationat com.nerve.huotong.web.WebApplication.main(WebApplication.java:21)... 8 moreCaused by: java.lang.ClassNotFoundException: org.springframework.boot.SpringApplicationat java.net.URLClassLoader.findClass(Unknown Source)at java.lang.ClassLoader.loadClass(Unknown Source)at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:94)at java.lang.ClassLoader.loadClass(Unknown Source)... 9 more
至此我們要設(shè)置LOADER_PATH,如下
java -Dloader.path="libs/" -jar ht-ui-web.jar便可以看到熟悉的Spring Boot 啟動(dòng)信息了。
還有另外一個(gè)做法是,把resources/public直接丟到libs下(就是跟上一步剝離出來的jar包放在一起),結(jié)構(gòu)如下:
這樣也是可以的(不過要注意不能跟真實(shí)項(xiàng)目中自己寫的靜態(tài)資源重名)。
經(jīng)過上面的瘦身,每次迭代開發(fā)開的Jar包就顯得苗條多了。
插些題外話
Spring Boot 中的 banner.txt
. ____ _ __ _ _/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \\\/ ___)| |_)| | | | | || (_| | ) ) ) )' |____| .__|_| |_|_| |_\__, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v1.4.3.RELEASE)
想要修改這個(gè)文本的話,只需要在resources下新建banner.txt即可。
這里可以自定義banner:http://patorjk.com/software/taag
你還有什么想要補(bǔ)充的嗎?
看完這篇文章,你有什么收獲?歡迎在留言區(qū)與10w+Java開發(fā)者一起討論~
最后,關(guān)注公眾號(hào)互聯(lián)網(wǎng)架構(gòu)師,在后臺(tái)回復(fù):2T,可以獲取我整理和創(chuàng)作的 Java 系列教程非常齊全。
1、2019 年 9 月全國程序員工資統(tǒng)計(jì),你是什么水平?
3、從零開始搭建創(chuàng)業(yè)公司后臺(tái)技術(shù)棧
5、37歲程序員被裁,120天沒找到工作,無奈去小公司,結(jié)果懵了...
6、滴滴業(yè)務(wù)中臺(tái)構(gòu)建實(shí)踐,首次曝光
