springboot项目打包优化,项目过程中会依赖其他很多jar包,如果打包太大,服务器网速不给力,上传服务器会很慢,此时可以对打包进行优化,增量部署,如果版本变化,需要重新上传依赖的jar到lib里面。所以如果每次都是全量,请忽略此文。
spring boot打瘦身包
方式一
1.在pom的 <plugins>
标签下添加spring-boot-maven-plugin,该配置会在打包的时候把第三方lib排除
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 指定该Main Class为全局的唯一入口 -->
<mainClass>com.xfw.community.MicroCommunityApplication</mainClass>
<!--把第三方jar包打入jar -->
<includeSystemScope>true</includeSystemScope>
<fork>true</fork>
<!-- 设置为ZIP,此模式下spring-boot-maven-plugin会将Manifest.MF文件中的Main-Class设置为org.springframework.boot.loader.PropertiesLauncher -->
<layout>ZIP</layout>
<includes>
<!--去除在生产环境中不变的依赖-->
<!--<excludeGroupIds>-->
<!--org.springframework.boot-->
<!--</excludeGroupIds>-->
<include>
<!-- 排除所有Jar -->
<groupId>nothing</groupId>
<artifactId>nothing</artifactId>
</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
<!--可以把依赖的包都打包到生成的Jar包中 -->
</goals>
</execution>
</executions>
</plugin>
2.添加maven-dependency-plugin插件,把排除的lib复制出来放到编译后的target/lib目录
<!-- 分离lib,第一次分离后,后续可不用打包 -->
<plugin>
<!--这个插件就是把依赖的jar包复制出来放到编译后的target/lib目录,并且在打包时候排除内部依赖-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<includeScope>compile</includeScope>
</configuration>
</execution>
</executions>
</plugin>
3.把lib包和项目打出来的jar包放到服务器,启动时新增参数-Dloader.path=lib/
,指定lib路径,完整启动命令如:
java -Dloader.path=lib/ -jar xxx.jar
方式二
1.使用maven-jar-plugin插件
更换maven的jar打包插件,先前使用的是spring-boot-maven-plugin来打包,这个插件会将项目所有的依赖打入BOOT-INF/lib下,替换为maven-jar-plugin
- addClasspath表示需要加入到类构建路径
- classpathPrefix指定生成的Manifest文件中Class-Path依赖lib前面都加上路径,构建出lib/xx.jar
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven.jar.plugin.version}</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.xxx.Start</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
2.拷贝依赖到jar外面的lib目录(和方式一的步骤2一致)
3.此时把jar包和lib包放到服务器同一级目录下即可启动(无需指定lib目录了)
java -jar xxx.jar
使用外部的application.yml
有时候我们只改动配置文件,不想重新打包,可以使用外部的application.yml文件
1.在和jar包同级的目录下新建一个config目录,放入application.yml文件
这里不用打包的jar里面的application.yml文件而用外部的application.yml文件,因为boot读取配置有一个优先级,放在jar包外面config目录优先级最高,主要是便于从外部修改配置,而不是改jar包中的application.yml文件。优先级如下:
- 当前目录的config目录下
- 当前目录
- classpath的config目录下
- classpath的根目录
2.注意一个依赖的坑
我多次通过java -jar的方式启动项目总是报如下错误:
ClassNotFoundException: org.springframework.boot.SpringApplication
后来发现时一个依赖的问题,问题详情可以见这个博客:
SpringBoot使用yaml作为配置文件之坑
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.21</version>
</dependency>
3.启动项目
这里不用在置顶lib的目录,并且加入–debug可以让你可以看到比较详细的启动日志
ava -jar xxx.jar --debug
全自动化步骤
前面介绍的步骤中,需要手动的拷贝application.yml文件,并且jar包内外都存在配置,总感觉怪怪的。这里引入一种自动化配置,将所有东西打成zip文件,直接发布到服务目录,解压后,即可启动。
1.还是同上面方法二的步骤1,2所示,指定打包插件和拷贝依赖的插件。
2.排除resources下面的yml(因为我们需要把它放在jar外部,不能让jar打包插件将其打入jar包classpath下去)
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/application.yml</exclude>
<<!---->exclude>**/*.yml</exclude>
</excludes>
</resource>
</resources>
上面这种排除*.yml配置文件的办法,有可能会在IDEA编译器启动的时候报错,下面的排除方法不会引起报错:(二选一即可)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lid/</classpathPrefix>
<mainClass>com.xxx.Start</mainClass>
</manifest>
</archive>
<!-- 排除配置文件 -->
<excludes>
<exclude>*.yml</exclude>
</excludes>
</configuration>
</plugin>
3.使用maven-assembly-plugin自定义打包
具体打包详情在assembly.xml配置中指定
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<!-- 打包后的包名是否包含assembly的id名 -->
<appendAssemblyId>false</appendAssemblyId>
<!-- 指定最后tar或者zip包的名字 -->
<finalName>packageName</finalName>
<descriptors>
<!-- 引用的assembly配置文件,可以用多个,即可以同时打包多个格式的包 -->
<descriptor>src/main/resources/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<!-- phase加入package后,则在执行maven package时就可以调用maven-assembly-plugin插件定义的打包方式 -->
<execution>
<!--名字任意 -->
<id>make-assembly</id>
<!-- 绑定到package生命周期阶段上 -->
<phase>package</phase>
<goals>
<!-- 只运行一次 -->
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
assembly.xml具体配置如下:
- 将application.yml放在外部config目录下
- 所有依赖打成zip压缩包
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>package</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>*.yml</include>
</includes>
<filtered>true</filtered>
<outputDirectory>${file.separator}config</outputDirectory>
</fileSet>
<fileSet>
<!-- 需要打包的路径 -->
<directory>src/main/resources/runScript</directory>
<!-- 打包后输出的路径,自定义 -->
<outputDirectory>${file.separator}bin</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.build.directory}/lib</directory>
<outputDirectory>${file.separator}lib</outputDirectory>
<includes>
<!-- 打包需要包含的文件 -->
<include>*.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>${file.separator}</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>