【包教包会系列】springboot将依赖jar打到指定位置

目录

[Springboot fat jar](#Springboot fat jar)

优势

劣势

普通jar

优势

劣势

如何打包

maven-dependency-plugin插件

maven-assembly-plugin插件

插件综合对比

插件打包功能对比


Spring boot fat ja r

Springboot fat jar打包的时候可以把项目本身jar和所需依赖的jar包都打包到同一个spring fat jar中。而传统的jar包只包含项目本身自己的代码部分,运行时需要手动添加并指定依赖和配置应用服务器等。而 fat Jar 是一个自包含、可独立运行的jar文件。也就是 fat Jar = 应用代码 + 所有依赖 + 内嵌服务器 + 启动器。

优势

  1. 部署简单:一个jar文件搞定,无需安装 Tomcat
    1. 环境一致:开发、测试、生产环境完全一致
      1. 快速启动:java -jar 即可运行
        1. 微服务友好:适合容器化(Docker)方便快速部署。

劣势

不方便增量替换jar,许多jar(如Spring自己的jar)都带有数字签名。替换后,签名文件(META-INF/*.SF, *.RSA)与内容不匹配,导致安全校验失败则jar启动失败。需要通过jar本身提供的命令进行替换内部依赖的jar包得操作,这样就比较麻烦。

为什么会有增量替换依赖jar这种需求?有的客户喜欢做增量升级,比如一个项目有30个jar,但是升级功能所需的代码部分只涉及5个jar包,所以客户就想只替换这个5个jar包完成服务升级。这样做的好处就是:jar包体积小方便内网或邮件传输(每次邮件到内网附件大小还有限制),代码改动范围的风险可控。

普通jar

普通jar打包的时候,当前项目包含启动器部分的代码会自行打包一个jar包内。而项目运行所需的依赖jar包会打到指定的位置,运行时通过java -cp 命令指定classpath去加载这些依赖的jar。

优势

这里能想到的优势就是方便快速替换增量的jar做版本迭代,jar包体积小方便内网传输,做到代码改动范围的风险可控。尤其是对大型多模块的maven项目来说,项目自身代码就有很多模块这种,可以考虑以这种方式打包。

劣势

个人感觉除了优势以外对比springboot fat jar就都是劣势了。

如何打包

比如我要将项目运行时除项目本身的jar以外的所需的依赖jar都打包到指定的位置,比如项目工作目录下的libs目录下,方式有以下两种。

maven-dependency-plugin 插件

XML 复制代码
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <includeScope>
                    runtime
                </includeScope>
                <outputDirectory>
                    ${project.build.directory}/libs
                </outputDirectory>
                //这里可以控制各种打包的过滤条件:详情请参考仓库位置:org\apache\maven\plugins\maven-dependency-plugin\版本\maven-dependency-plugin-xxx.jar!\META-INF\maven\plugin.xml
            </configuration>
        </execution>
    </executions>
</plugin>

maven-assembly-plugin 插件

相比 maven-dependency-plugin 插件,maven-assembly-plugin 则更加灵活,不仅可以控制依赖的jar包,还可以控制单个文件、多个文件、以及目录等等。这样在打包的时候更加灵活。请参考之前的博文:https://blog.csdn.net/weixin_38357164/article/details/156639593?fromshare=blogdetail&sharetype=blogdetail&sharerId=156639593&sharerefer=PC&sharesource=weixin_38357164&sharefrom=from_link

代码例子如下:

XML 复制代码
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2.1</version>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
        <execution>
            <id>xxx</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <descriptors>
                    <descriptor>src/main/resources/assembly-xxx.xml</descriptor>
                </descriptors>
            </configuration>
        </execution>
    </executions>
</plugin>

然后在项目main/resources目录下创建assembly-xxx.xml文件。在文件中定义打包的逻辑,代码例子如下:

XML 复制代码
<assembly
        xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>hengShengBank</id>
    <includeBaseDirectory>false</includeBaseDirectory>
    <formats>
        <format>dir</format>
    </formats>
    <dependencySets>
        <dependencySet>
            <!--构建包时不包含项目自身的jar,也就是项目本身的jar单独打到默认的target目录下-->
            <useProjectArtifact>false</useProjectArtifact>
            <!--将scope为runtime的所有依赖包打到libs目录下-->
            <outputDirectory>libs</outputDirectory>
            <!--这里可以配置过滤条件-->
            <excludes>
                <exclude>依赖的groupId:依赖的artifactId</exclude>
            </excludes>
        </dependencySet>
    </dependencySets>
</assembly>

插件综合对比

特性 maven-dependency-plugin maven-assembly-plugin
主要目的 管理依赖关系 创建分发包
输出格式 复制文件到目录 ZIP, TAR, JAR, WAR等归档格式
包含内容 主要是依赖JAR 依赖 + 项目构建输出 + 任意文件
使用场景 依赖分析、复制、解压 制作完整发布包、安装包
控制粒度 依赖级别控制 文件级别控制
典型任务 copy-dependencies, unpack single, dir

插件打包功能对比

打包特性 maven-dependency-plugin maven-assembly-plugin
创建归档文件 只能复制文件 主要功能
多种格式支持 ZIP, TAR, JAR等
自定义目录结构 只能指定输出目录 完整目录结构控制
包含任意文件 只能处理依赖 通过fileSet支持
多模块打包 通过moduleSet支持
文件权限设置 支持Unix/Windows权限
文件过滤 includes/excludes 更强大的过滤选项
属性过滤 支持属性替换

后续会出一个maven插件详解的文章~敬请期待!

======================

喜欢求个关注,回归持续更新

======================

相关推荐
请叫我头头哥17 小时前
SpringBoot进阶教程(八十九)rabbitmq长链接及域名TTL,多机房切换配置重连能力
rabbitmq·springboot
她说..1 天前
策略模式+工厂模式实现审批流(面试问答版)
java·后端·spring·面试·springboot·策略模式·javaee
tb_first1 天前
SSM速通4
java·jvm·spring·tomcat·maven·mybatis
人道领域1 天前
javaWeb从入门到进阶(maven高级进阶)
java·spring·maven
weixin_704266051 天前
Maven入门:构建与依赖管理全解析
java·maven
Elias不吃糖1 天前
Day1 项目启动记录(KnowledgeDock)
java·springboot·登陆·项目启动
A懿轩A1 天前
【Maven 构建工具】Maven 生命周期完全解读:clean / default / site 三套生命周期与常用命令
java·log4j·maven
大佐不会说日语~1 天前
Docker Compose 部署 Spring Boot 应用 502 Bad Gateway 问题排查与解决
spring boot·docker·gateway·maven·故障排查
过期动态2 天前
Java开发中的@EnableWebMvc注解和WebMvcConfigurer接口
java·开发语言·spring boot·spring·tomcat·maven·idea
A懿轩A2 天前
【Maven 构建工具】从零到上手 Maven:安装配置 + IDEA 集成 + 第一个项目(保姆级教程)
java·maven·intellij-idea