📦SpringBoot项目jar包启动瘦身
SpringBoot项目jar包瘦身
一、背景:
现在使用SpringBoot微服务的场景下,一个项目可能会引入很多个jar包依赖,这样带来的问题就是jar包特别臃肿,包含动辄几百MB的jar包文件。
这样每次进行发布的时候,需要传输这么大的jar包文件,不单单是对资源带宽的消耗,也白白浪费很多时间等待……
为了解决这种部署的痛点,我们可以将经常要变的jar包和项目class打包在一块,将很少、不会被修改的jar包单独打包到lib下,像以往的mvc项目部署一样。
常用的pom属性如下:
${project.build.sourceDirectory}
:项目的主源码目录,默认为 src/main/java${project.build.testSourceDirectory}
:项目的测试源码目录,默认为 src/test/java${project.build.directory}
:项目构件输出目录,默认为 target/${project.outputDirectory}
:项目主代码编译输出目录,默认为 target/classes/${project.testOutputDirectory}
:项目测试代码编译输出目录,默认为 target/test-classes/${project.groupId}
:项目的 groupId${project.artifactId}
:项目的 artifactIdproject.version
:项目的version,与{project.version}:项目的 version,与project.version:项目的version,与{version}等价project.build.fianlName
:项目打包输出文件的名称。默认为{project.build.fianlName}:项目打包输出文件的名称。默认为project.build.fianlName:项目打包输出文件的名称。默认为{project.artifactId}-${project.version}
二、瘦身原理
解压下正常打包的jar包,可以看到将所有的jar包都打包在了一块
项目虽然依赖会很多,但是当版本迭代稳定之后,依赖基本就不会再变动了。
如果可以把这些不变的依赖提前都放到服务器上,打包的时候忽略这些依赖,那么打出来的Jar包就会小很多,直接提升发版效率。
三、如何打包和启动项目
打包
mvn clean package
<build> <plugins> <!-- 分离lib 生产时打包放开,使用:java -Dloader.path=./lib -jar xxx.jar --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <!--使用的SpringBoot版本--> <version>2.5.14</version> <configuration> <layout>ZIP</layout> <!-- 这里是填写需要包含进去的jar, 必须项目中的某些模块,会经常变动,那么就应该将其坐标写进来 如果没有则nothing ,表示不打包依赖 --> <includes> <include> <groupId>nothing</groupId> <artifactId>nothing</artifactId> </include> <!-- 要打包在主jar包中的依赖(要经常进行修改的) --> <!--<include> <groupId>com.asp</groupId> <artifactId>asp-common</artifactId> </include>--> </includes> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.8</version> <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>
如上面配置所示,将common依赖单独打包,而其他依赖被打包到了target下的lib下了,如下图:
需要注意:如果lib下和主jar包下都有asp-common-5.0.0.jar,那么系统会去使用lib下的jar包(即使主jar包是最新的),所以常用的依赖包打到主jar包后,需要单独去删除lib下的jar包。
启动
java -Dloader.path=./lib -jar xxx.jar --spring.profiles.active=dev
更新(2023-12-23):将配置文件打包放在外面
这样配置文件就会在jar包当前目录的config下,在SpringBoot中默认加载配置文件等级最高的也就是和jar包同级目录的config中的配置。
<!--分离配置文件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <executions> <execution> <id>copy-resources</id> <phase>package</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <resources> <resource> <directory>src/main/resources</directory> <!-- 指定参与构建的resources--> <includes> <include>*.**</include> </includes> </resource> </resources> <outputDirectory>${project.build.directory}/config</outputDirectory> </configuration> </execution> </executions> </plugin>
配合上面分离lib,完整的pom配置如下:
<build> <plugins> <!-- 分离lib 生产时打包放开,使用:java -Dloader.path=./lib -jar xxx.jar --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <!--使用的SpringBoot版本--> <version>2.5.14</version> <configuration> <layout>ZIP</layout> <!-- 这里是填写需要包含进去的jar, 必须项目中的某些模块,会经常变动,那么就应该将其坐标写进来 如果没有则nothing ,表示不打包依赖 --> <includes> <include> <groupId>nothing</groupId> <artifactId>nothing</artifactId> </include> <!-- 要打包在主jar包中的依赖(要经常进行修改的) --> <!--<include> <groupId>com.asp</groupId> <artifactId>asp-common</artifactId> </include>--> </includes> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.8</version> <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> <!--分离配置文件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <executions> <execution> <id>copy-resources</id> <phase>package</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <resources> <resource> <directory>src/main/resources</directory> <!-- 指定参与构建的resources--> <includes> <include>*.**</include> </includes> </resource> </resources> <outputDirectory>${project.build.directory}/config</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build>