近期有个SpringBoot的项目需要频繁更新,但是每次上传到服务器上几十MB,实在是花时间,所以打算优化打包方案,将第三方依赖外置
背景
近期有个SpringBoot的项目需要频繁更新,但是每次上传到服务器上几十MB,实在是花时间,所以打算优化打包方案,将第三方依赖外置
流程
- 首先使用SpringBoot打包插件将第三方排除,但是一些版本号同步更新的本地模块依赖需要放到一个jar中
- 使用maven dependency插件将第三方依赖复制到构建目录中
- 使用maven过滤功能实现一个启动脚本
- 使用assembly打包一个完整版,包括boot jar,第三方依赖,启动脚本
- 第一次部署使用完整版,后续更新只需要上传boot jar就行了
实现方法
首先在 resource 目录中准备一个脚本
内容如下
1 2
| java -Dloader.path=lib/ -Dfile.encoding=utf-8 -jar @project.build.finalName@.jar
|
其中 @project.build.finalName@ 是最后生成的可执行jar的文件名
path指定第三方依赖目录
其次修改pom文件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| <build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources>
<finalName>${project.artifactId}-${project.version}-${spring.active}</finalName>
<plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>xxx.Application</mainClass>
<layout>ZIP</layout> <executable>true</executable> <includes> <include> <groupId>xxx.xxx</groupId> <artifactId>upload-starter</artifactId> </include> <include> <groupId>xxx.xxx</groupId> <artifactId>pay</artifactId> </include> <include> <groupId>${project.parent.groupId}</groupId> <artifactId>swagger-starter</artifactId> </include> </includes>
</configuration> </plugin>
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> <overWriteReleases>false</overWriteReleases> <excludeGroupIds> ${project.parent.groupId},xxx.xxx </excludeGroupIds> </configuration> </execution> </executions> </plugin>
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptors> <descriptor>assembly.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals>
</execution> </executions> </plugin> </plugins> </build>
|
在 pom.xml 同级目录创建 assembly.xml
内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <assembly> <id>release</id> <formats> <format>zip</format> </formats> <includeBaseDirectory>false</includeBaseDirectory>
<fileSets> <fileSet> <directory>${project.build.directory}/lib</directory> <outputDirectory>/lib</outputDirectory> </fileSet> </fileSets> <files> <file> <source>target/${build.finalName}.jar</source> <outputDirectory>/</outputDirectory> </file> <file> <source>${project.build.directory}/classes/start.sh</source> <outputDirectory>/</outputDirectory> <destName>start.bat</destName> </file> <file> <source>${project.build.directory}/classes/start.sh</source> <outputDirectory>/</outputDirectory> <destName>start.sh</destName> </file> </files> </assembly>
|
最终效果

可以很明显的看出两个方式打包的大小差异
完整版的目录结构

2021-04-30 补充
maven-dependency-plugin 的exclude对于包的判断有些与众不同
项目包名为com.bc,然后有个依赖包为 com.bc.uc 结果我发现这个依赖包不会被copy。
因此只能放弃 copy 插件,改为使用 assembly 提供的依赖copy,这样还少了一次copy操作
2021-07-19 补充
使用assembly或者maven-dependency-plugin有个问题,会把scope为test的依赖一并copy打包,指定scope=runtime也不好用,于是升级插件版本到3.3.0,就ok了
但是maven-dependency-plugin有<includeScpre>可以排除test环境的包