由于行业原因,公司开发的系统都是在内网上运行,且内网中不可访问公网环境。在每次发包的时候都需要在本地打好 jarwar 包,通过入域U盘或者内网传输软件将程序包发送到内网的某个电脑上,通过堡垒机上传到内网某个服务器中进行发布。

最近由于入域U盘物理损坏,重新申请U盘需要审核,一段时间内估计下不来,导致每次发包都通过传输软件传,一些项目包一两百兆还好,有些老项目包动不动就500m起步,传输速度还奇慢无比,导致就算是一个细小的页面修改也要花大量时间在传包的问题上。所以想将项目中的依赖抽离出来保存到服务器里面,每次打包只打java文件,执行jar时通过指定依赖目录的方式进行引用。因为项目依赖大多数情况下是不变的,通过分离maven项目的依赖和class可以大大提高程序包的体积,方便传输。

SpringBoot操作方法

废话不多说,如何配置实现。

添加 spring-boot-maven-plugin 插件

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <mainClass>cn.tangseng233.demo.DemoApplication</mainClass>
        <includeSystemScope>true</includeSystemScope>
        <fork>true</fork>
        <layout>ZIP</layout>
        <includes>
            <include>
                <groupId>nothing</groupId>
                <artifactId>nothing</artifactId>
            </include>
        </includes>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

通过Spring Initializr 生成的 Springboot 项目会默认带这个插件,只要补充一些插件里面的参数即可。 核心参数是 <include> 里面的 nothing , 该插件用于打包的时候排除依赖用的。

添加 maven-dependency-plugin 插件

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy</id>
            <!--绑定package阶段执行该插件-->
            <phase>package</phase>
            <goals>
                <!--该插件的目的是复制依赖-->
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <!--输出路径-->
                <outputDirectory>C:/Users/tangseng/Desktop/libs</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

该插件是用于将项目中的所有依赖复制到指定的目录中。<outputDirectory> 打包时复制依赖输出的目录,后期我们只要将这个目录里面的依赖复制到服务器保存即可。第一次运行该插件之后,通常在不修改pom文件,不新增或修改项目依赖的时候不需要用到这个,因为lib里面已经有固定的依赖包了,可以直接把该插件注释掉,防止生成多余的libs还要删掉,等加入依赖或修改依赖时再放开注释,重新导一份到运行环境即可。

运行项目

java -Dloader.path=/your/lib/path/ -jar  demo.jar

结果

原来打包体积

image-20220226100158177

分离后打包体积

image-20220226103008777

可以看到分离后的程序包大大缩小了,可以大量减少网络传输所需要的时间了。

一些额外的知识

Maven本质上是一个插件执行框架;所有工作都由插件完成。

核心插件和其他插件的列表:

https://maven.apache.org/plugins/index.html

Maven默认(default)生命周期执行会经历以下的阶段,我们通常可以特定执行到某个生命周期的某个阶段,如常用的package 打包。通过将插件绑定到生命周期的某阶段,可以实现通过插件增减功能。Maven 生命周期及生命周期中内置绑定的插件说明参考Maven官网文档-生命周期

maven-dependency-plugin(找依赖)

可以在上面的插件列表的Tool分类中找到 dependency 插件,在 dependency 的目的(goals)中可以找到该插件的目的。

image-20220225170922187

点进去可以找到更加详细的配置参数,在该下面可以找到usage page页面,描述了插件的使用方法。

spring-boot-maven-plugin(打包)

Spring Boot Maven 插件在Apache Maven中提供 Spring Boot 支持。它允许您打包可执行 jar 或 war 档案、运行 Spring Boot 应用程序、生成构建信息并在运行集成测试之前启动您的 Spring Boot 应用程序。

该插件的官方页面:

https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/htmlsingle/

主要用到的是repackage(重新打包)这个功能,通过<include> 定义打包时引入的依赖列表,nothing为打包时不引入所有依赖。