【包教包会系列】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插件详解的文章~敬请期待!

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

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

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

相关推荐
我真会写代码9 小时前
SSM(指南一)---Maven项目管理从入门到精通|高质量实操指南
java·spring·tomcat·maven·ssm
Dragon Wu13 小时前
Spring Security Oauth2.1 授权码模式实现前后端分离的方案
java·spring boot·后端·spring cloud·springboot·springcloud
vx1_Biye_Design14 小时前
基于Spring Boot+Vue的学生管理系统设计与实现-计算机毕业设计源码46223
java·vue.js·spring boot·spring·eclipse·tomcat·maven
闻哥1 天前
从测试坏味道到优雅实践:打造高质量单元测试
java·面试·单元测试·log4j·springboot
qq_336313932 天前
javaweb-maven单元测试
java·开发语言·maven
索荣荣2 天前
Web基石:Java Servlet 全面指南:从基础原理到 Spring Boot 实战
java·springboot·web
计算机毕设指导62 天前
基于微信小程序的校园二手交易系统【源码文末联系】
java·spring boot·spring·微信小程序·小程序·tomcat·maven
2301_818732062 天前
项目启动报错,错误指向xml 已解决
xml·java·数据库·后端·springboot
多多*2 天前
2026年最新 测试开发工程师相关 Linux相关知识点
java·开发语言·javascript·算法·spring·java-ee·maven
lang201509283 天前
Tomcat Maven插件:部署与卸载的架构设计
java·tomcat·maven