Maven uber-jar(带依赖的打包插件) spring-boot-maven-plugin

news2024/11/24 22:42:23

文章目录

  • 最基础的 spring-boot-maven-plugin 使用
  • 指定入口类
  • 安装部署原始 Jar 包到仓库
  • 保持原始Jar包名称,为 spring-boot-maven-plugin 生成的Jar包添加名称后缀
  • 打包时排除依赖
  • 建议将生成的Jar解压后了解一下整体结构
  • 与其他常用打包插件比较

本文是对 spring-boot-maven-plugin 常用配置的介绍,更详细的学习请参照 Spring Boot Maven Plugin 官方文档

通过使用 spring-boot-maven-plugin 插件进行 Maven 的打包操作,可以将项目中依赖的 Jar 包一同添加到最终的项目 Jar 包内,这个插件有很多执行目标,对于打包来说,主要使用 repackage目标,建议使用时与 Maven 生命周期的 package 阶段绑定

不管 pom.xml 是否声明了 Maven 的默认打包插件 maven-jar-plugin,也不管是否声明了其他打包插件,maven-jar-plugin 都会在 package 阶段最先执行,而 spring-boot-maven-plugin 插件的 repackge 目标,正是对 maven-jar-plugin 打包后的 Jar 包进行二次打包,同时将项目依赖的 Jar 添加进去

这中打包后带依赖的 Jar 包一般称为 uper-jarfat-jar


最基础的 spring-boot-maven-plugin 使用

这个插件的最基础使用方式非常简单,pom.xml 中添加如下配置即可,重点在 15~29 行:

<!-- 模拟项目使用了依赖 -->
<dependencies>
    <!-- 依赖 commons-lang3 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.12.0</version>
    </dependency>
</dependencies>

<!-- 对项目构建进行配置 -->
<build>
    <plugins>
    	<!-- 引入 spring-boot-maven-plugin 插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.3.7.RELEASE</version>
            <executions>
                <execution>
                	<!-- 绑定 Maven 生命周期的 package 阶段 -->
                    <phase>package</phase>
                    <goals>
						<!-- package 阶段执行时,让其调用插件的 repackage 目标 -->
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

上面的配置添加后,我们就可以在 pom.xml 的所在目录运行 Maven 生命周期命令 mvn package,当命令运行后,会将打包结果存放到 ${project.build.directory} 中(默认是 target 目录),如下图:

spring打包

上图中,我们重点关注两个文件:

  • ares5k-package-1.0-SNAPSHOT.jar:spring-boot-maven-pluginmaven-jar-plugin 生成的 Jar 包进行二次打包后的 Jar 包,这个 Jar 包内已经包函项目的依赖了

  • ares5k-package-1.0-SNAPSHOT.jar.original:原始 Jar 包,maven-jar-plugin 生成的不包含项目依赖的 Jar 包,spring-boot-maven-plugin 为了避免原始 Jar 包和新 Jar 包名字冲突,对原始 Jar 包进行了重命名,添加了 original 后缀

ares5k-package-1.0-SNAPSHOT.jar 进行解压后,可以在 \BOOT-INF\lib 目录内看到项目依赖的 Jar 包:

项目依赖

虽然配置中没有指定入口类,但是这个 Jar 包仍然是可执行的,其在打包时会在 ${project.build.outputDirectory}(默认是 target/classes) 目录中依次向内查找,直至找到 .class文件为止,那么这个 .class 文件就是我们的入口类并被添加到项目的 MANIFEST.MF 中,如果在同一目录内出现多个 .class 文件,那么最后一个会成为入口类,例如下图:

默认入口类


指定入口类

想打破 spring-boot-maven-plugin 自动查找入口类的规则,从而自定义入口类,参考 19~22 行配置即可 :

<build>
    <plugins>
        <!-- 引入 spring-boot-maven-plugin 插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.3.7.RELEASE</version>
            <executions>
                <execution>
                    <!-- 绑定 Maven 生命周期的 package 阶段 -->
                    <phase>package</phase>
                    <goals>
                        <!-- package 阶段执行时,让其调用插件的 repackage 目标 -->
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
            <!-- 修改插件属性 -->
            <configuration>
                <!-- 指定入口类 -->
                <mainClass>com.ares5k.AA</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

安装部署原始 Jar 包到仓库

配置 spring-boot-maven-plugin 后,当执行 mvn install 或 mvn deploy 时,会将带依赖的 Jar 包安装或部署到仓库,有时候我们希望测试方便所以希望本地的包是包函依赖的,而安装部署的是原始包,这时候就可以如下配置,20~23 行:

<!-- 对项目构建进行配置 -->
<build>
    <plugins>
        <!-- 引入 spring-boot-maven-plugin 插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.3.7.RELEASE</version>
            <executions>
                <execution>
                    <!-- 绑定 Maven 生命周期的 package 阶段 -->
                    <phase>package</phase>
                    <goals>
                        <!-- package 阶段执行时,让其调用插件的 repackage 目标 -->
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
            <!-- 修改插件属性 -->
            <configuration>
                <!-- 将原始包安装或部署到仓库 -->
                <attach>false</attach>
            </configuration>
        </plugin>
    </plugins>
</build>

保持原始Jar包名称,为 spring-boot-maven-plugin 生成的Jar包添加名称后缀

前面演示了,spring-boot-maven-plugin 执行 repackage 后会将 原始 Jar 包 重命名为 .original 结尾的形式,如果想保持原始 Jar 包的名称,那么就需必须修改新 Jar 包的名称,不然会命名冲突,通过如下方式可以为 新 Jar 包 添加名称后缀,20~24 行:

<!-- 对项目构建进行配置 -->
<build>
    <plugins>
        <!-- 引入 spring-boot-maven-plugin 插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.3.7.RELEASE</version>
            <executions>
                <execution>
                    <!-- 绑定 Maven 生命周期的 package 阶段 -->
                    <phase>package</phase>
                    <goals>
                        <!-- package 阶段执行时,让其调用插件的 repackage 目标 -->
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
            <!-- 修改插件属性 -->
            <configuration>
                <!-- 给 spring-boot-maven-plugin 生成的 Jar 包添加名称后缀,
                设置后 原始 Jar 包就不会改名为 .original 形式了-->
                <!-- 这个地方名称随便写 -->
                <classifier>spring-boot</classifier>
            </configuration>
        </plugin>
    </plugins>
</build>

效果如下:

新Jar包添加名称后缀


打包时排除依赖

打包时排除不需要的依赖,20~29 行:

<!-- 对项目构建进行配置 -->
<build>
    <plugins>
        <!-- 引入 spring-boot-maven-plugin 插件 -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.3.7.RELEASE</version>
            <executions>
                <execution>
                    <!-- 绑定 Maven 生命周期的 package 阶段 -->
                    <phase>package</phase>
                    <goals>
                        <!-- package 阶段执行时,让其调用插件的 repackage 目标 -->
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
            <!-- 修改插件属性 -->
            <configuration>
                <!-- 排除打包后不需要的依赖 -->
                <excludes>
                    <!-- 排除 commons-lang3 -->
                    <exclude>
                        <groupId>org.apache.commons</groupId>
                        <artifactId>commons-lang3</artifactId>
                    </exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>

建议将生成的Jar解压后了解一下整体结构

spring-boot-maven-plugin 打包后的项目 Jar 包中,不仅仅只是添加了依赖的 Jar 包,还多了很多 Spring 自己的文件,比如 META-INF/MANIFEST.MF 中真正的入口类其实是 Spring 的类,并不是我们设置的入口类,而我们设置的入口类是被 Spring 的这个类调用后才运行起来的。还有很多小细节,感兴趣的建议将项目Jar 解压后,研究一下


与其他常用打包插件比较

除了 spring-boot-maven-plugin 之外,常用的打包插件还有 maven-jar-pluginmaven-shade-plugin,使用方法在我其他文章中也有记录,在此将它们作一个简单的比较

spring-boot-maven-plugin

spring-boot-maven-plugin 是 Spring 提供的一个 Maven 打包插件,可以通过 maven 的插件命令运行,但是一般习惯将它与 maven 生命周期绑定,然后通过 maven 生命周期命令运行,它的特点是可以将项目中依赖的 Jar 包添加到最终生成的项目 Jar 包中

spring-boot-maven-plugin 主要是对 maven-jar-plugin 生成的项目 Jar 包进行二次打包,并将项目依赖的 Jar 包添加进项目的 Jar 包中

maven-jar-plugin

maven 生命周期中 package 阶段的默认插件,不管是否在 pom.xml 中主动声明,也不管是否有其他的 package 阶段插件被绑定,其在 package 阶段都会被最先执行

使用 maven-jar-plugin 打包时,不会将依赖的 Jar 包添加到生成的项目 Jar 包中,所以当项目中使用依赖时,需要自己准备依赖的 Jar 包,这样 maven-jar-plugin 打出的项目 Jar 包才能被成功运行

maven-shade-plugin

maven-shade-plugin 也可以将项目的依赖打进最终的项目 Jar 包中,但是其与 spring-boot-maven-plugin 不同的是,spring-boot-maven-plugin 是直接将依赖的 Jar 包放进项目的 Jar 包中,而 maven-shade-plugin 则是将依赖的 Jar 包解压,然后将解压后的文件放进最终的项目 Jar 包中

maven-shade-plugin 将依赖的 Jar 包解压后添加到项目的 Jar 包中的做法,为 maven-shade-plugin 带来了另一个重要的功能 <重命名>,因为将依赖的 Jar 包解压后都是以文件形式存在,所以 maven-shade-plugin 支持对对依赖的某个具体文件进行重命名,maven-shade-plugin 在重命名时,不只是将文件名字修改,连我们项目中对其引用的地方都会一同修改

重命名的做法可以避免版本冲突,想详细了解的可以参考我 maven-shade-plugin 的文章

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/596577.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

04 【计算属性 侦听属性】

04 【计算属性 侦听属性】 1.计算属性 1.1插值语法实现 <title>姓名案例_插值语法实现</title><div id"root">姓&#xff1a;<input type"text" v-model"firstName"> <br/>名&#xff1a;<input type"…

Python自动人工智能训练数据增强工具 | DALI介绍(含代码)

Python自动人工智能训练数据增强工具 | DALI介绍(含代码) 文章目录 Python自动人工智能训练数据增强工具 | DALI介绍(含代码)自动数据增强方法DALI 和条件执行使用 DALI 自动增强使用 DALI 的自动增强性能尝试使用 DALI 进行自动增强 深度学习模型需要数百 GB 的数据才能很好地…

回归测试:优先级(Coverage 的适应度函数)

回归测试&#xff1a;优先级 介绍 在确定优先级时&#xff0c;我们的目标是为测试用例找到一个好的顺序。理想情况下&#xff0c;我们希望尽早发生任何故障。这可以加快整体开发过程&#xff0c;例如&#xff1a; 有时&#xff0c;一旦发现失败&#xff0c;我们就会停止测试。…

HashMap详细讲解-面试题大全

HashMap底层数据结构是什么&#xff1f;1.7和1.8有何不同 1.7是 数组 链表&#xff0c;1.8 是数组 &#xff08;链表 或者 红黑树&#xff09; 当链表的元素比较多的时候&#xff0c;链表就会转换成红黑树&#xff0c;红黑树的元素减少了&#xff0c;红黑树也会转换成链表 为…

前后分离的优势

1.可以实现真正的前后端解耦&#xff0c;前端服务器使用nginx。 前端/WEB服务器放的是css&#xff0c;js&#xff0c;图片等等一系列静态资源&#xff08;甚至你还可以css&#xff0c;js&#xff0c;图片等资源放到特定的文件服务器&#xff0c;例如阿里云的oss&#xff0c;并使…

【计算机网络】前后端分离,HTTP协议,网络分层结构,TCP,强缓存/协商缓存

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录 前后端分类HTTP协议HTTP组成HTTP的版本HTTP的请求方式HTTP请求头HTTP响应头强缓存和协商缓存 HT…

Linux ls -l输出文件信息详解

在linux中&#xff0c;我们知道一切皆为文件&#xff0c;经常我们会使用ls -l去查看文件的信息&#xff0c;今天会大家详细讲解一下ls -l输出的文件属性信息。 1.ls -l输出 命令&#xff1a; ls -l 通过ls -l命令输出&#xff0c;我们可以看到上图中的属性信息输出&#xff…

【珍藏版】生态系统NPP及碳源、碳汇模拟、土地利用变化、未来气候变化、空间动态模拟

由于全球变暖、大气中温室气体浓度逐年增加等问题的出现&#xff0c;“双碳”行动特别是碳中和已经在世界范围形成广泛影响。碳中和可以从碳排放&#xff08;碳源&#xff09;和碳固定&#xff08;碳汇&#xff09;这两个侧面来理解。陆地生态系统在全球碳循环过程中有着重要作…

五、JSP05 分页查询及文件上传

五、JSP 分页查询及文件上传 5.1 使用分页显示数据 通过网络搜索数据时最常用的操作&#xff0c;但当数据量很大时&#xff0c;页面就会变得冗长&#xff0c;用户必须拖动才能浏览更多的数据 分页是把数据库中需要展示的数据逐页分步展示给用户 以分页的形式显示数据&#xff…

Elasticsearch 8.X “图搜图”实战

1、什么是图搜图&#xff1f; "图搜图"指的是通过图像搜索的一种方法&#xff0c;用户可以通过上传一张图片&#xff0c;搜索引擎会返回类似或者相关的图片结果。这种搜索方式不需要用户输入文字&#xff0c;而是通过比较图片的视觉信息来找到相似或相关的图片。这项…

Tomcat服务器的安装即相关介绍

一、Tomcat的安装步骤 1、访问官网下载点击此处进入Tomcat官网&#xff1b; 2、在下图所示位置点击想要下载的版本下载&#xff0c;这边演示的是以Tomcat8为演示对象&#xff1b; 3、进入下载页面如下图所示&#xff0c;根据系统类型和版本选择合适的安装包&#xff1b; 4、下…

Wampsever升级增加php5.6的方法过程

1、下载wampserver2.5&#xff0c;文件包名&#xff1a;wampserver2.5-Apache-2.4.9-Mysql-5.6.17-php5.5.12-64b.exe https://sourceforge.net/projects/wampserver/files/WampServer%202/Wampserver%202.5/ 这个版本只有40M&#xff0c;包含&#xff1a; Apache-2.4.9&#x…

SpringCloud OpenFeign 学习

SpringCloud OpenFeign 文章目录 SpringCloud OpenFeign1 OpenFeign介绍2 OpenFeign-应用实例3 OpenFeign 测试 1 OpenFeign介绍 OpenFeign 是个声明式 WebService 客户端&#xff0c;使用 OpenFeign 让编写 Web Service 客户端 更简单 它的使用方法是定义一个服务接口然后在上…

【Java 抽象类抽象方法】什么是抽象类方法,如何定义,起什么作用?

博主&#xff1a;_LJaXi Or 東方幻想郷 专栏&#xff1a; Java | 从入门到入坟 Java 抽象类 & 抽象方法 抽象类的概念 &#x1f445;抽象方法的概念 &#x1f42c;抽象类和抽象方法结合使用 &#x1f984; Java中的抽象类和抽象方法是面向对象编程中的重要概念&#xff0c;…

【系统学习】Java基础4之lamda表达式和函数式接口

lamda表达式与函数式接口 lamda表达式 语法格式一&#xff1a;无参&#xff0c;无返回值 Lambda 需要一个参数&#xff0c;但是没有返回值 语法格式三&#xff1a;数据类型可以省略&#xff0c;因为可由编译器推断得出&#xff0c;称为“类型推断” 语法格式四&#xff1a;…

MySQL和Redis之间的存储区别

概述 MySQL是一种关系型数据库&#xff0c;而Redis是一种键值对存储数据库。虽然它们都是用来存储和管理数据的&#xff0c;但是它们在很多方面都有不同&#xff0c;但是它们在存储策略、日志存储方式、硬盘存储、数据恢复等方面都有一定的区别。 数据类型 MySQL支持多种数据…

电脑怎么通过网络传输文件?

可以通过网络在电脑之间传输文件吗&#xff1f; “由于天气的原因&#xff0c;我的老板决定让所有员工在家工作。但是我很多工作文件都在公司的电脑中&#xff0c;怎么才能将公司的文件远程传输到我家里的电脑上&#xff1f;电脑可以通过网络远程传输文件吗&#xff1f;” …

计算机网络 | I/O模型、网络模型(OSI七层及TCP/IP四层)

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

Python快速实现网页工具的利器

Python快速实现网页工具的利器 Streamlit是一个基于Python的Web应用程序开发框架&#xff0c;它具有快速开发、交互式、易于使用等特点。使用Streamlit&#xff0c;开发者可以很容易地将Python代码转换为漂亮的、交互式的Web应用程序&#xff0c;无需繁琐的前端开发经验。 如果…

什么是浪涌保护器SPD

浪涌保护器&#xff08;SPD&#xff09;&#xff0c;也称为电涌保护器&#xff0c;是为各种电子设备&#xff0c;仪器和通信线路提供安全保护的电子设备。当由于外部干扰在电路或通信电路中突然产生尖峰电流或电压时&#xff0c;浪涌保护装置可以在很短的时间内传导和分流&…