Springboot的jar包分离

前往原站点查看

2022-12-19 23:44:36

    上一次实现了前后端分包,每次可以单独管理前端或者后端程序的上线,从而方便维护。但是随着例行维护发现,springboot每次整体打包,都要往服务器传递近百来兆的一个大的jar包,非常费力,所以就想着进行一个简单的优化,从而使每次上传的量尽量小。

    造成jar包非常大的原因其实很简单,通过解压jar包,查看结构就会发现,占用大头在第三方jar包,比如说腾讯云的java-sdk约莫有二十多M等。而实际情况是:我的个人主页模块基本定型了,依赖基本不会产生大的变动了,所以想要将这个jar包分离,单独放在一个lib文件夹下,每次只需要打包核心代码上传即可!

基本方式概述

    使用spring-boot-maven-plugin插件来进行管理,相应的理论基础可以参考官方介绍:Spring Boot Maven Plugin Documentation。里面有着关于这个插件的详细描述与使用方式。

    大致上可以总结几个要点:

1. 如果依赖设置parent为spring-boot-starter-parent,那么默认配置了goal为repackage,无需再手动配置。

  不过有时候可能会使用自己的parent或者个人喜欢明确的引入依赖,那么可能需要自己配置goal。

  设置为repackage可以打包成可执行的jar包或者war。如果没有main函数,后续设置layout=NONE也可以实现打包不可执行的jar包。

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

2. devtools默认是自动排除在外的,当然也可以使用excludeDevtools配置来显示的去除。若要再war包生效,需要设置spring-boot-devtools的optional为true或者scope为    provided。这个工具可以重写manifest文件,管理了启动类和主类集。如果不奏效需要再springboot插件配置,而非jar插件。MAIN-CLASS取决于layout的设置。

  其中layout有以下几种选择:

    - JAR :可执行jar

    - WAR :可执行war

    - ZIP :类似于jar,不过使用PropertiesLauncher。是DIR的别称。

    - NONE:打包依赖和资源,但是没有打包一个引导加载器。

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>${start.class}</mainClass>
                <layout>ZIP</layout>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

3. excludes和includes可以去除或者加入指定依赖到最终包中。不配置默认加入全部。

4.可以自定义layer,可以拆分到不同layers中,具体的可以参考官方文档的配置介绍。

实际应用

    有了理论基础,那么接下来就是付诸实践。首先我们需要以ZIP作为layout,让生成的配置mainclass为PropertiesLauncher。然后把所有包都排除:

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>top.dreamcenter.dreamcenter.DreamcenterApplication</mainClass>
                    <layout>ZIP</layout>
                    <includes>
                        <include>
                            <groupId>nothing</groupId>
                            <artifactId>nothing</artifactId>
                        </include>
                    </includes>
                </configuration>
            </plugin>
        </plugins>
    </build>

    等到clean+package后,我们查看MANIFEST文件的配置查看是否生效。确实生效了。

        
    接着,我们把第三方jar包全部放到lib中,之后使用 java -jar -Dloader.path=lib xxx.jar 执行测试:

        
    结果发现报错了,结果百度,发现BASE64Encoder已经在java后续版本取消掉了,而我开发默认的JAVA_HOME是16版本的,所以运行会找不到这个类。

    在命令行输入set path=... 临时改变path,然后测试运行成功了!

        
    要能使用-Dloader.path要先让layout设置为ZIP哦!

    最后,来看一下最终jar包大小:

        


    NICE!甚至不到1M,以后传输上来说就方便不少啦!




上一篇: 分布式项目搭建的一些小结
下一篇: 服务监测与redis序列化