0%

SpringBoot Jar瘦身

  由于springboot打出来的jar包含了第三方引入的jar包,所以这就会导致打出来的jar包臃肿而庞大,本文针对此问题对springboot jar包进行瘦身。

  三方jar包分离版:将第三方依赖的jar包导出到指定的目录下,在springboot jar包启动命令添加参数指定三方依赖jar包的路径。

  maven配置自动化版:三方依赖jar包分离,资源文件分离,打出的jar包只包含当前项目的class文件,同时在jar包的MANIFEST.MF文件中指定三方依赖jar包和资源文件的路径,启动脚本无需添加路径参数,达到自动化的效果。

一、三方jar包分离版

第一步:使用maven-dependency-jar插件将第三方依赖jar包分离到指定目录
第二步:使用springboot-maven-jar插件打出可执行jar包
第三步:jar包启动命令参数添加第三方依赖jar包的目录

1.1、导出三方jar包

  • 可以通过解压工具,对 jar 进行解压,复制出 lib 下的依赖jar包(比较麻烦不推荐)

  • 使用maven命令将三方依赖导出,建议使用绝对路径

    1
    2
    # -DoutputDirectory参数指定jar包导出的目录
    mvn dependency:copy-dependencies -DoutputDirectory=/Users/guanxu/jar/lib -DincludeScope=runtime
  • 配置到pom文件中,打包时自动将三方依赖导出,见1.2节pom文件配置(推荐使用)

1.2、pom文件配置

  • 使用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
    <build>
    <plugins>

    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.8</version>

    <!--将依赖的三方jar包, 导出到指定目录, 当前指定的是默认的target目录-->
    <executions>
    <execution>
    <id>copy-dependencies</id>
    <phase>package</phase>
    <goals>
    <goal>copy-dependencies</goal>
    </goals>
    <configuration>
    <outputDirectory>/Users/guanxu/jar/lib</outputDirectory>
    <excludeTransitive>false</excludeTransitive>
    <stripVersion>false</stripVersion>
    <silent>true</silent>
    </configuration>
    </execution>
    </executions>
    </plugin>

    <!--springboot打包插件(瘦身版), 不包含三方jar包-->
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>2.2.1.RELEASE</version>

    <executions>
    <execution>
    <id>repackage</id>
    <goals>
    <goal>repackage</goal>
    </goals>
    </execution>
    </executions>

    <configuration>
    <!--用来配置可执行jar包中Main-Class的类型,这里一定要设置为ZIP,使打的jar包中的Main-Class为PropertiesLauncher-->
    <layout>ZIP</layout>

    <!--将需要保留的jar包,按照groupId和artifactId(注意两个都是必填项)include进来。nothing代表不存在的依赖包,意思就是什么依赖包都不引入-->
    <includes>
    <include>
    <groupId>nothing</groupId>
    <artifactId>nothing</artifactId>
    </include>
    </includes>
    </configuration>
    </plugin>

    </plugins>
    </build>

1.3、启动jar包指定第三方jar包目录

使用java -jar命令时加上 -Dloader.path 参数指定第三方jar包的目录,因为上述操作三方jar导出的目录是/Users/guanxu/lib,所以指定参数也是这个目录

1
java -Dloader.path=/Users/guanxu/jar/lib -jar xxx.jar

二、maven配置自动化版

相比于第一种方式,可以更进一步简化jar包,不仅将第三方依赖jar包,并且将resources资源目录分离,同时在打可执行jar包的时候,将依赖jar包目录以及resources资源目录打到MANIFEST.MF文件中,无需在启动脚本添加路径参数即可启动
第一步:使用maven-dependency-jar插件将第三方依赖jar包分离到指定目录
第二步:使用maven-resources-plugin插件将resources资源文件分离到指定目录
第三步:使用maven-jar-plugin插件打出可执行jar包,同时指定三方依赖jar包目录,resources资源文件目录,一起打到MANIFEST.MF文件中

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
89
<build>
<plugins>
<!--将依赖的三方jar包, 导出到指定目录, 当前指定的是target/lib目录-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<!--是否排除间接依赖,间接依赖也要拷贝-->
<excludeTransitive>false</excludeTransitive>
<!--是否带上版本号-->
<stripVersion>false</stripVersion>
<silent>true</silent>
<!--依赖范围-->
<includeScope>runtime</includeScope>
</configuration>
</plugin>

<!--将资源文件, 导出到指定目录, 当前指定的是target/resources目录-->
<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>
</execution>
</executions>
<configuration>
<outputDirectory>${project.build.directory}/resources</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>*/**</include>
</includes>
</resource>
</resources>
</configuration>
</plugin>

<!--maven构建的jar不包含依赖文件, 显式剔除配置文件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<!--将配置文件排除在jar包-->
<excludes>
<exclude>*.properties</exclude>
<exclude>*.yml</exclude>
</excludes>
<!--生成MANIFEST.MF的设置-->
<archive>
<!--META-INF是否包含pom.xml和pom.properties文件-->
<addMavenDescriptor>false</addMavenDescriptor>
<!--生成MANIFEST.MF的设置-->
<manifest>
<useUniqueVersions>false</useUniqueVersions>
<!--指定第三方依赖的jar目录-->
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.xxx.MainApplication</mainClass>
</manifest>
<manifestEntries>
<!--MANIFEST.MF 中 Class-Path 加入自定义路径,多个路径用空格隔开-->
<!--指定resources资源目录-->
<Class-Path>resources/</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>