spring boot 工程 jar 包瘦身
spring boot 工程 jar 包瘦身
Spring Boot项目的pom.xml文件中一般都会带有spring-boot-maven-plugin插件,该插件的作用就是会将依赖的jar包全部打包进去。
但是该文件包含了所有的依赖和资源文件,会导致打出来的包会比较大。
而如果我们使用一般的打包命令时
mvn clean package
不会把依赖的jar包也打进去,这样打出来的包就会很小。
问题描述
但当一个系统上线运行后,肯定会有需求迭代和Bug修复,那也就免不了进行重新打包部署。
此时有一个场景:线上有一个紧急BUG,并且BUG很快被定位并且修复,其实就是一行代码的事情,现在代码修改好了并且完成了构建然后开始打包交付时发现,jar包很大,一直在上传。
而当经常需要迭代发布,每一次都上传一个庞大的jar包文件,会浪费很多时间。
此时就需要为jar包瘦瘦身,降低jar包文件的大小。
瘦身原理
一个spring boot正常的打包,包含所有依赖时打出的jar包有120多M:
解压查看内部有三个包,BOOT-INF、META-INFO、org
打开BOOT-INF
- classes: 存放当前项目编译好的代码,这部分是非常小的。
- lib: 存放我们所依赖的 jar 包,lib部分会很大。
原理
当一个项目的依赖越多,lib包就会越大。虽然依赖多,但是当版本迭代稳定之后,依赖基本就不会再变动了。
我们就可以把这些不变的依赖提前都放到服务器上,打包的时候忽略这些依赖,只打本项目编译好的文件,这样打出来的jar包就会很小,提高发版效率。
配置实现
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 设置主函数 -->
<mainClass>cn.yanggl.xxxMain</mainClass>
<layout>ZIP</layout>
<!--这里是填写需要包含进去的jar,
必须项目中的某些模块,会经常变动,那么就应该将其坐标写进来
如果没有则nothing ,表示不打包依赖 -->
<includes>
<!-- 需要一起打包到项目jar包的依赖 -->
<include>
<groupId>nothing</groupId>
<artifactId>nothing</artifactId>
</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</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>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<!-- 不需要导出的依赖 -->
<excludeArtifactIds>
cn.yanggl
</excludeArtifactIds>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
调整了配置之后,再次打包我们会发现发现target目录中多了个lib文件夹,里面保存了所有的依赖jar。本项目的jar包只有几百K。
当include标签只填groupId标签时,表示groupId标识下的所有依赖都包含
问题
启动问题
Spring Boot默认打包方式,将所有依赖文件全部打入项目jar包,我们在启动项目时可以通过
java -jar xxx.jar
直接运行。
而当进行瘦身之后,因为我们已经将项目依赖到外部lib包,我们就不能再通过以上那种方式启动,而是要通过通过-Dloader.path指定lib的路径:
java -jar -Dloader.path="/lib" xxx.jar
依赖问题
如果你有一个项目A,它依赖于项目B,而项目B又依赖于项目C,那么项目A实际上也是依赖于项目C的。
这种情况下,如果使用了spring-boot-maven-plugin并配置了includes标签,实际上是在设置要包含哪些依赖,而不是要排除哪些依赖。
所以,当你把B模块添加到includes标签下时,实际上你只是包含了B模块本身,而不是它的所有依赖,例如C。
当想要A也包含C的依赖,则需要显示的添加到includes标签下
lib包更新问题
现在项目A显示的引入了项目B,当项目C更新或者添加了新地依赖D的时候,项目A就需要重新构建以便获取最新版本的
B以及其依赖,并且将最新的lib包更新到A的服务器上。