起因:使用SpringBoot開發項目,引用了很多依賴,最終打包成可運行的jar文件時,往往有幾十M,或者更大,上傳服務器要浪費很長時間。
優化方式一
1. 依賴分離
SpringBoot可運行的jar文件很大是因為,jar文件里包含了很多依賴jar,所以才會生成幾十M的文件。
解決辦法是在maven配置中,使用插件:
<build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> <plugins> <!--使用該插件打包 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <useUniqueVersions>false</useUniqueVersions> <addClasspath>true</addClasspath> <classpathPrefix>/data/server/system-demo/libs/</classpathPrefix> <mainClass>com.zh.system.SystemApplication</mainClass> </manifest> <manifestEntries> </manifestEntries> </archive> </configuration> </plugin> <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>/data/server/system-demo/libs/</outputDirectory> </configuration> </execution> </executions> </plugin> <!-- 跳過單元測試 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skipTests>true</skipTests> </configuration> </plugin> </plugins> </build>
maven-jar-plugin插件的作用是jar運行時使用的配置,屬性包括:classpathPrefix指定外部jar的路徑,mainClass指定jar包的啟動類
maven-dependency-plugin插件的作用是打包時,指定依賴jar拷貝的目錄。
/data/server/system-demo 是我准備的項目運行jar包的目錄。
我這里使用的路徑都是/data/server/system-demo/libs/,如果你是在windows系統下編譯打包項目,你可以到項目所在的workspace的磁盤根目錄下查找,會發現也生成了這樣的目錄,項目相關的jar包都拷貝到這里了。在服務器上創建目錄/data/server/system-demo/libs/,並且把項目需要的jar包都上傳到此目錄。
2. 配置文件管理
我的項目中的配置文件按服務器環境配置了幾套,如下圖:
在application.yml的代碼,使用這條命令指定加載的子配置文件:spring.profiles.active: test
這樣管理配置很方便,避免多個服務器環境之間的參數切換,帶來混淆的問題。但如果你修改代碼之后,每個環境都要發布一遍,就會需要修改spring.profiles.active的值后,重復打包的問題。
所以,按照SpringBoot的運行加載規則,如果在運行jar統計目錄有config文件夾,會被提前加載的。我們只需要在/data/server/system-demo/下創建一個config文件夾。並只上傳此環境的配置文件就好了。
方法1:正常打包,這些配置文件會在jar包的config目錄下,我們只要刪掉這些文件,在jar包運行時,就會自動讀取/data/server/system-demo/config 里面的文件了,避免了很多重復打包工作。
方法2:在打包時,是可以使用maven插件把配置文件排除的,我還沒試。
3. 總結
當項目運行時,最終在system-demo目錄下,會有2個文件夾,2個文件。
system-demo-1.0-SNAPSHOT.jar -------SpringBoot啟動jar包
config ---------項目的配置文件
libs -----------項目的依賴jar
nohup.out ------nohup命令運行jar文件之后,生成的臨時日志文件
優化方式二
1. 正常編譯JAR包,解壓出lib文件夾
POM文件如下:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.johnnian.App</mainClass> <layout>ZIP</layout> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugins> <build>
進入項目根目錄,執行命令:mvn clean install
將編譯后的Jar包解壓,拷貝 BOOT-INF 目錄下的lib文件夾 到目標路徑;
2. 修改pom.xml配置,編譯出不帶 lib 文件夾的Jar包
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.johnnian.App</mainClass> <layout>ZIP</layout> <includes> <include> <groupId>nothing</groupId> <artifactId>nothing</artifactId> </include> </includes> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugins> <build>
配置完成后,再次執行編譯:mvn clean install
生成的 Jar 包體積明顯變小,外部的 jar 包已經不會被引入了。
3. 運行編譯后的Jar包
將 步驟1 解壓出來的lib文件夾、步驟2編譯的jar包放在同一個目錄, 運行下面命令:
java -Dloader.path=/path/to/lib -jar /path/to/springboot-jsp-0.0.1-SNAPSHOT.jar
或者在maven中輸入一下命令導出需要用到的jar包
mvn dependency:copy-dependencies -DoutputDirectory=F:\ideaWorkPlace\AnalysisEngine\lib -DincludeScope=runtime
備注:將/path/to/改成實際的路徑。-Dloader.path=lib文件夾路徑
最終目錄文件結構是:
├── lib #lib文件夾
└── springboot-jsp-0.0.1-SNAPSHOT.jar
說明:
1、通常,一個工程項目架構確定后,引入的jar包基本上不會變,改變的大部分是業務邏輯;
2、后面如果需要變更業務邏輯,只需要輕量地編譯工程,大大提高項目部署的效率。
步驟1: 正常編譯JAR包,解壓出lib文件夾