使用maven对springboot项目进行瘦身分离jar的多种处理方案

 更新时间:2024年02月05日 11:22:33   作者:老码龙  
springboot项目打包一般我们都使用它自带的spring-boot-maven-plugin插件,这个插件默认情况下,会把所有的依赖包全部压缩到一个jar里面,今天给大家分享几种方案来如何减小我们的打包文件,需要的朋友可以参考下

前言

springboot项目打包一般我们都使用它自带的spring-boot-maven-plugin插件,这个插件默认情况下,会把所有的依赖包全部压缩到一个jar里面。在有时这给我们的部署或者更新带来很多的不方便,有的项目很大,最终的打包文件甚至可以达到几百M,有时可能我们只修改了一个小bug,更新时却要上传几百M的安装包,极度不方便,今天给大家分享几种方案来如何减小我们的打包文件,已方便我们的更新操作。
我们构造一个测试项目,具体的依赖如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

默认情况下我们直接运行打包命令:

mvn clean -DskipTests package

完成后,我们检查文件大小:

在这里插入图片描述

有18M,下面我们来进行瘦身处理

一、方案一(修改自带的spring-boot-maven-plugin插件)

我们可以使用自带的spring-boot-maven-plugin插件进行修改,然后再配合另外两个插件,这两个插件就是:maven-jar-plugin和maven-dependency-plugin,可以轻松完成,下面我们来具体操作。

在pom.xml文件中的plugins节点下加入下面的配置:

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
            <classesDirectory>target/classes/</classesDirectory>
            <archive>
                <manifest>
                    <mainClass>com.example.testmvnpkgexespringboot.TestApplication</mainClass>
                    <!-- 打包时 MANIFEST.MF文件不记录的时间戳版本 -->
                    <useUniqueVersions>false</useUniqueVersions>
                    <addClasspath>true</addClasspath>
                    <classpathPrefix>lib/</classpathPrefix>
                </manifest>
                <manifestEntries>
                    <Class-Path>.</Class-Path>
                </manifestEntries>
            </archive>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
            <execution>
                <id>copy-dependencies</id>
                <phase>package</phase>
                <goals>
                    <goal>copy-dependencies</goal>
                </goals>
                <configuration>
                    <type>jar</type>
                    <includeTypes>jar</includeTypes>
                    <outputDirectory>
                        ${project.build.directory}/lib
                    </outputDirectory>
                    <overWriteReleases>false</overWriteReleases>
                    <overWriteSnapshots>false</overWriteSnapshots>
                    <overWriteIfNewer>true</overWriteIfNewer>
                </configuration>
            </execution>
        </executions>
    </plugin>

    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
            <!--重写包含依赖,包含不存在的依赖,jar里没有pom里的依赖 -->
            <includes>
                <include>
                    <groupId>null</groupId>
                    <artifactId>null</artifactId>
                </include>
            </includes>
            <layout>ZIP</layout>
            <!--使用外部配置文件,jar包里没有资源文件 -->
            <addResources>true</addResources>
            <outputDirectory>${project.build.directory}</outputDirectory>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <goal>repackage</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>

下面进行打包:

mvn clean -DskipTests package

然后再查看文件大小:

在这里插入图片描述

我们发现,文件只有102K,而且这里多了一个lib文件,那么要运行这个文件,lib包就是必须的,我们直接运行jar包进行测试:

java -jar pkg-sb.jar

发现正常启动,如果我们把lib包删掉,在运行,这时就会报错。因此我们在发布项目的时候,lib和我们自己的jar必须再同级目录下,当然也可以修改maven-jar-plugin中的配置,大家可以自行研究。

最后我们使用assembly来制作一个ZIP发布包,assembly的配置如下:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>package</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>true</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/lib</directory>
            <outputDirectory>\lib</outputDirectory>
        </fileSet>
        <fileSet>
            <directory>${project.build.directory}</directory>
            <outputDirectory>\</outputDirectory>
            <includes>
                <include>pkg-sb.jar</include>
            </includes>
        </fileSet>
        
    </fileSets>
</assembly>

二、方案二(使用spring-boot-thin-maven-plugin插件)

这个插件功能比较强大,如果你的项目想要弄的高大上一点,可以选择这个插件,我们先看下效果。
首先在项目的pom.xml里面加入下面配置:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot.experimental</groupId>
            <artifactId>spring-boot-thin-layout</artifactId>
            <version>1.0.31.RELEASE</version>
        </dependency>
    </dependencies>
</plugin>
<plugin>
    <groupId>org.springframework.boot.experimental</groupId>
    <artifactId>spring-boot-thin-maven-plugin</artifactId>
    <version>1.0.31.RELEASE</version>
    <executions>
        <execution>
            <!-- Download the dependencies at build time -->
            <id>resolve</id>
            <goals>
                <goal>resolve</goal>
            </goals>
            <inherited>false</inherited>
        </execution>
    </executions>
</plugin>

然后我们直接打包:

mvn clean -DskipTests package

查看打包后的结果:

在这里插入图片描述

这里我们看jar包只有12k,比方案一的还小,但是下面多了一个thin文件夹打开再看:

在这里插入图片描述

最下面的repository就是依赖的jar包。如果我们要运行这个jar,就需要运行thin/root下的Java包:

java -jar target/thin/root/pkg-sb.jar

运行结果:

2024-01-31 16:51:29.955  INFO 16785 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-01-31 16:51:29.955  INFO 16785 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 635 ms
2024-01-31 16:51:30.087  INFO 16785 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2024-01-31 16:51:30.229  INFO 16785 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 12345 (http) with context path ''
2024-01-31 16:51:30.232  INFO 16785 --- [           main] c.e.t.TestApplication                    : Started TestApplication in 1.411 seconds (JVM running for 4.141)

说明启动正常。

下面我们来讲下这个插件的强大之处。

1、spring-boot-thin-maven-plugin的原理其实就是把我们项目中的所有依赖当成转换成maven的本地库

2、如果目标机上安装了maven环境,我们可以直接来运行jar包,这是这个jar会自动启动maven来下载我们项目中需要的jar依赖包。你可以使用调试模式来启动jar,然后观察他的启动过程:

调试模式启动:

java -jar -Dthin.debug=true pkg-sb.jar

然后运行情况如下:

[root@localhost test]# java -jar -Dthin.debug=true pkg-sb.jar 
Cached launcher found: /root/.m2/repository
Using launcher: /root/.m2/repository/org/springframework/boot/experimental/spring-boot-thin-launcher/1.0.31.RELEASE/spring-boot-thin-launcher-1.0.31.RELEASE-exec.jar
1月 31, 2024 5:02:20 下午 org.springframework.boot.loader.thin.ThinJarLauncher launch
信息: Version: 1.0.31.RELEASE
1月 31, 2024 5:02:20 下午 org.springframework.boot.loader.thin.PathResolver resolve
信息: Extracting dependencies from: jar:file:/root/test/pkg-sb.jar!/, with profiles []
1月 31, 2024 5:02:20 下午 org.springframework.boot.loader.thin.PathResolver loadProperties
信息: Searching for properties in: jar:file:/root/test/pkg-sb.jar!/
1月 31, 2024 5:02:20 下午 org.springframework.boot.loader.thin.PathResolver loadProperties
信息: Searching for properties in: classpath:/
1月 31, 2024 5:02:20 下午 org.springframework.boot.loader.thin.PathResolver loadProperties
信息: Searching for properties in: file:./
1月 31, 2024 5:02:20 下午 org.springframework.boot.loader.thin.PathResolver extract
信息: Extracting dependencies from: URL [jar:file:/root/test/pkg-sb.jar!/META-INF/maven/org.example/test-sb-lib/pom.xml], with profiles []
1月 31, 2024 5:02:21 下午 org.springframework.boot.loader.thin.MavenSettingsReader loadSettings
信息: No settings found at: /root/.m2/settings.xml
1月 31, 2024 5:02:22 下午 org.springframework.boot.loader.thin.DependencyResolver dependencies
信息: Computing dependencies from pom and properties
1月 31, 2024 5:03:11 下午 org.springframework.boot.loader.thin.DependencyResolver dependencies
信息: Resolved: org.springframework.boot:spring-boot-starter-web:2.2.5.RELEASE=/root/.m2/repository/org/springframework/boot/spring-boot-starter-web/2.2.5.RELEASE/spring-boot-starter-web-2.2.5.RELEASE.jar
1月 31, 2024 5:03:11 下午 org.springframework.boot.loader.thin.DependencyResolver dependencies
信息: Resolved: org.springframework.boot:spring-boot-starter:2.2.5.RELEASE=/root/.m2/repository/org/springframework/boot/spring-boot-starter/2.2.5.RELEASE/spring-boot-starter-2.2.5.RELEASE.jar
1月 31, 2024 5:03:11 下午 org.springframework.boot.loader.thin.DependencyResolver dependencies

这里他自动去下载了我们项目依赖的jar包并自动存放到${user.home}/.m2 下面,

3、我们可以手动指定依赖库的位置,启动命令如下:

java -jar -Dthin.debug=true -Dthin.root=. pkg-sb.jar 

这样他会启动maven把依赖库下载到我当前的目录下

4、还可以手动指定去下载依赖库的maven仓库地址,命令如下:

java -jar -Dthin.debug=true -Dthin.root=. -Dthin.repo=http://192.168.101.170:8081/repository/maven-public pkg-sb.jar 

这里我们使用了前面我们自己搭建的私有库,因此我们能很好的去控制项目的运行。

5、也可以采用离线模式去运行,这就需要我们要把打包后产生的依赖一起进行打包,这种方式和方案一的模式一样,但是这种对目标机就没有maven环境的依赖,我们再使用assembly来制作一个ZIP的发布包:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>package</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>true</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/thin/</directory>
            <outputDirectory>\</outputDirectory>
        </fileSet>
    </fileSets>
</assembly>

6、spring-boot-thin-maven-plugin的更多用法,大家可以参照官网,点击这里

总结

1、以上给大家分享了2中瘦身方案,反正各自都有一定的缺点和优点,大家根据实际情况进行选择

2、方案一比较传统,整个过程中规中矩,没什么亮点,但实用性很强,缺点就是如果有新增依赖,在更新的时候就需要更新lib下的jar包,需要把新增的加入进去。

3、方案二很有创意,而且功能很强大,能玩出很多姿势来,如果采用离线模式也就和方案一没区别,采用在线模式缺点就是要依赖maven环境,但是也可以将maven和项目整个打包,然后编写脚本来实现自带maven环境。大家可以自己去尝试。

4、这两种方式都能实现对springboot项目的瘦身处理,对更新来说方便很多。

5、如果有自己的私有库,我们可以把项目进行分模块化处理,核心业务用一个单独的jar来实现,这样方案二能利用maven实现优雅更新

6、虽然有的同学会想到利用docker来运行,对更新来说也很方便,其实方式二也将maven环境打入docker镜像,然后利用在线模式来运行,这样可以大大减少docker镜像的大小,后面的章节我们可以继续来研究

以上就是使用maven对springboot项目进行瘦身分离jar的多种处理方案的详细内容,更多关于maven对springboot瘦身分离的资料请关注脚本之家其它相关文章!

相关文章

  • 使用java从乱码文本中解析出正确的文本

    使用java从乱码文本中解析出正确的文本

    这篇文章主要介绍了使用java从乱码文本中解析出正确的文本的方法,需要的朋友可以参考下
    2014-04-04
  • Java日常练习题,每天进步一点点(51)

    Java日常练习题,每天进步一点点(51)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-08-08
  • 解决项目没有build path的问题

    解决项目没有build path的问题

    这篇文章主要介绍了解决项目没有build path的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • java实现的汉字转五笔功能实例

    java实现的汉字转五笔功能实例

    这篇文章主要介绍了java实现的汉字转五笔功能,结合具体实例形式分析了java基于字符串遍历与编码转换等操作实现五笔编码获取的相关操作技巧,需要的朋友可以参考下
    2017-06-06
  • Spring框架事务属性中事务隔离级别与传播行为全面讲解

    Spring框架事务属性中事务隔离级别与传播行为全面讲解

    这篇文章主要介绍了Spring框架声明式事务的事务隔离级别和事务传播行为,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-11-11
  • Java实现Windows计算器界面

    Java实现Windows计算器界面

    这篇文章主要为大家详细介绍了Java实现Windows计算器界面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • Spring 使用JavaConfig实现配置的方法步骤

    Spring 使用JavaConfig实现配置的方法步骤

    这篇文章主要介绍了Spring 使用JavaConfig实现配置的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • 解决spring-boot使用logback的大坑

    解决spring-boot使用logback的大坑

    这篇文章主要介绍了解决spring-boot使用logback的大坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • SpringBoot中@MessageMapping注解的原理及使用详解

    SpringBoot中@MessageMapping注解的原理及使用详解

    这篇文章主要介绍了SpringBoot中@MessageMapping注解的原理及使用详解,@MessageMapping注解是Spring Boot提供的一个重要的注解之一,它可以帮助我们处理WebSocket消息,需要的朋友可以参考下
    2023-07-07
  • JVM的基本介绍以及垃圾回收

    JVM的基本介绍以及垃圾回收

    垃圾回收(Garbage Collection,GC),顾名思义就是释放垃圾占用的空间,防止内存泄露,这篇文章主要给大家介绍了关于JVM垃圾回收的相关资料,需要的朋友可以参考下
    2021-09-09

最新评论