给你的 SpringBoot 工程部署的 jar 包瘦瘦身吧!

给你的 SpringBoot 工程部署的 jar 包瘦瘦身吧!

之前有写过一篇有关maven插件的文章:spring-boot-maven-plugin插件详解

一、需求背景

我们知道Spring Boot项目,是可以通过java -jar 包名 启动的。

那为什么Spring Boot项目可以通过上述命令启动,而其它普通的项目却不可以呢?

原因在于我们在通过以下命令打包时

mvn clean package 

一般的maven项目的打包命令,不会把依赖的jar包也打包进去的,所以这样打出的包一般都很小

给你的 SpringBoot 工程部署的 jar 包瘦瘦身吧!

但Spring Boot项目的pom.xml文件中一般都会带有spring-boot-maven-plugin插件。

该插件的作用就是会将依赖的jar包全部打包进去。该文件包含了所有的依赖和资源文件。

也就会导致打出来的包比较大。

给你的 SpringBoot 工程部署的 jar 包瘦瘦身吧!

打完包就可以通过java -jar 包名 启动,确实是方便了。

但当一个系统上线运行后,肯定会有需求迭代和Bug修复,那也就免不了进行重新打包部署。

我们可以想象一种场景,线上有一个紧急致命Bug,你也很快定位到了问题,就改一行代码的事情,当提交代码并完成构建打包并交付给运维。

因为打包的jar很大,一直处于上传中.......

如果你是老板肯定会发火,就改了一行代码却上传几百MB的文件,难道没有办法优化一下吗?

如今迭代发布时常有的事情,每次都上传一个如此庞大的文件,会浪费很多时间。

下面就以一个小项目为例,来演示如何瘦身。

二、瘦身原理

这里有一个最基础 SpringBoot 项目,整个项目代码就一个SpringBoot启动类,但是打包出来的jar就有20多M;

我们通过解压命令,看下jar的组成部分。

tar -zxvf spring-boot-maven-slim-1.0.0.jar 

给你的 SpringBoot 工程部署的 jar 包瘦瘦身吧!

我们可以看出,解压出来的包有三个模块

分为 BOOT-INFMETA-INForg 三个部分

打开 BOOT-INF

给你的 SpringBoot 工程部署的 jar 包瘦瘦身吧!

classes: 当前项目编译好的代码是放在 classes 里面的,classes 部分是非常小的。

lib: 我们所依赖的 jar 包都是放在 lib 文件夹下,lib部分会很大。

看了这个结构我们该如何去瘦身呢?

项目虽然依赖会很多,但是当版本迭代稳定之后,依赖基本就不会再变动了。

如果可以把这些不变的依赖提前都放到服务器上,打包的时候忽略这些依赖,那么打出来的Jar包就会小很多,直接提升发版效率。

当然这样做你肯定有疑问?

既然打包的时候忽略这些依赖,那通过java -jar 包名 还可以启动吗?

这种方式打的包,在项目启动时,需要通过-Dloader.path指定lib的路径,就可以正常启动

java -Dloader.path=./lib -jar xxx.jar 

三、瘦身实例演示

1、依赖拆分配置

只需要在项目pom.xml文件中添加下面的配置:

	<build> 		<plugins> 			<plugin> 				<groupId>org.springframework.boot</groupId> 				<artifactId>spring-boot-maven-plugin</artifactId> 				<configuration> 					<executable>true</executable> 					<layout>ZIP</layout> 					<!--这里是填写需要包含进去的jar,           必须项目中的某些模块,会经常变动,那么就应该将其坐标写进来           如果没有则nothing ,表示不打包依赖 --> 					<includes> 						<include> 							<groupId>nothing</groupId> 							<artifactId>nothing</artifactId> 						</include> 					</includes> 				</configuration> 			</plugin>  			<!--拷贝依赖到jar外面的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> 		</plugins> 	</build> 

再次打包

mvn clean package 

给你的 SpringBoot 工程部署的 jar 包瘦瘦身吧!

发现target目录中多了个lib文件夹,里面保存了所有的依赖jar。

给你的 SpringBoot 工程部署的 jar 包瘦瘦身吧!

自己业务相关的jar也只有小小的168kb,相比之前20.2M,足足小了100多倍;

这种方式打的包,在项目启动时,需要通过-Dloader.path指定lib的路径:

java -Dloader.path=./lib -jar spring-boot-maven-slim-1.0.0.jar 

给你的 SpringBoot 工程部署的 jar 包瘦瘦身吧!

虽然这样打包,三方依赖的大小并没有任何的改变,但有个很大的不同就是我们自己的业务包依赖包分开了;

在不改变依赖的情况下,也就只需要第一次上传lib目录到服务器,后续业务的调整、bug修复,在没调整依赖的情况下,就只需要上传更新小小的业务包即可;

2、自己其它项目的依赖如何处理?

我们在做项目开发时,除了会引用第三方依赖,也会依赖自己公司的其它模块。

比如

给你的 SpringBoot 工程部署的 jar 包瘦瘦身吧!

这种依赖自己其它项目的工程,也是会经常变动的,所以不宜打到外部的lib,不然就会需要经常上传更新。

那怎么做了?

其实也很简单 只需在上面的插件把你需要打进jar的填写进去就可以了

<plugin> 	<groupId>org.springframework.boot</groupId> 	<artifactId>spring-boot-maven-plugin</artifactId> 	<configuration> 		<executable>true</executable> 		<layout>ZIP</layout> 		<!--这里是填写需要包含进去的jar,如果没有则nothing --> 			<includes> 				<include> 					<groupId>com.jincou</groupId> 					<artifactId>xiaoxiao-util</artifactId> 				</include> 			</includes> 	</configuration> </plugin> 

这样只有include中所有添加依赖依然会打进当前业务包中。

四、总结

使用瘦身部署,你的业务包确实小了 方便每次的迭代更新,不用每次都上传一个很大的 jar 包,从而节省部署时间。

但这种方式也有一个弊端就是增加了Jar包的管理成本,多人协调开发,构建的时候,还需要专门去关注是否有人更新依赖。

声明: 公众号如需转载该篇文章,发表文章的头部一定要 告知是转至公众号: 后端元宇宙。同时也可以问本人要markdown原稿和原图片。其它情况一律禁止转载!

发表评论

评论已关闭。

相关文章