spring-boot-maven-plugin插件打包和java -jar命令执行原理
文章目录
- 1. Maven生命周期
- 2. jar包结构
- 2.1 不可执jar包结构
- 2.2 可执行jar包结构
- 3. spring-boot-maven-plugin插件打包
- 4. 执行jar原理
1. Maven生命周期
Maven的生命周期有三种:
- clean:清除项目构建数据,较为简单,不深入探讨;
- site:建立和部署项目站点,使用的较少,也不深入探讨;
- default:定义了项目构建时所需要的所有步骤,是Maven生命周期中最核心最重要的的部分。
本次要深入了解的便是default流程。其生命周期如下:
| 阶段 | 可否执行 | 说明 |
|---|---|---|
| validate | √ | 验证项目是否正确以及所有必要信息是否可用 |
| initialize | X | 初始化构建状态 |
| generate-sources | X | 生成编译阶段需要的所有源码文件 |
| process-sources | X | 处理源码文件,例如过滤某些值 |
| generate-resources | X | 生成项目打包阶段需要的资源文件 |
| process-resources | X | 处理资源文件,并复制到输出目录,为打包阶段做准备 |
| compile | √ | 编译源代码,并移动到输出目录 |
| process-classes | X | 处理编译生成的字节码文件 |
| generate-test-sources | X | 生成编译阶段需要的测试源代码 |
| process-test-sources | X | 处理测试资源,并复制到测试输出目录 |
| test-compile | X | 编译测试源代码并移动到测试输出目录中 |
| test | √ | 使用适当的单元测试框架(如junit)运行测试 |
| prepare-package | X | 在真正打包前执行一些必要的操作 |
| package | √ | 获取编译后的代码,并按照可发布的格式进行打包,如jar、war或ear文件 |
| pre-integration-test | X | 在集成测试执行之前,执行所需的操作,例如设置环境变量 |
| integration-test | X | 处理和部署所需的包到集成测试能够运行的环境中 |
| post-integration-test | X | 在集成测试被执行后执行必要的操作,例如清理环境 |
| verify | √ | 对集成测试的结果进行检查,以保证质量达标 |
| install | √ | 安装打包的项目到本地仓库,以供本地其它项目使用 |
| deploy | √ | 拷贝最终的包文件到远程仓库中,以共享给其它开发人员和项目 |
其中可以在Maven常见的Lifecycle中直接执行的有validate、compile、test、package、verify和deploy七种,一般在Maven的plugin标签中,可以通过配置如下配置来指定插件在某个阶段生效,需要注意的是不可随意配置,每个插件可处理的阶段都是不同的。(不配置则执行插件默认的)
<executions><execution><phase>XX</phase><goals><goal>XXXX</goal></goals></execution>
</executions>
今天要深入了解的spring-boot-maven-plugin插件就是在package阶段中生效的。
2. jar包结构
通常而言,jar包分为可执行jar包和不可执行jar包,顾名思义,可执行jar包即可通过命令java -jar直接执行,不可执行jar包通过命令java -jar执行则会报错。
2.1 不可执jar包结构
|-- _jar包根目录|-- 原项目class文件和resource文件|-- _META-INF|-- MANIFEST.MF|-- _maven|-- _项目目录|-- pom.properties|-- pom.xml
上面是经典的不可执行jar包目录,其中MANIFEST.MF文件内容如下:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: xxxxx
Created-By: Apache Maven 3.5.0
Build-Jdk: 1.8.0_151
这五项是最基本的,如果使用java -jar执行这些jar包,将会抛出错误码java.launcher.jar.error3,意为没找到Main-Class属性。不同语言展示的最终描述不同,由launcher+对应语言类转换,简体中文在launcher_zh_CN类中转换,{0}为jar包名称,内容如下:
{0}中没有主清单属性
英文在launcher类中转换,{0}为jar包名称,内容如下:
no main manifest attribute, in {0}
2.2 可执行jar包结构
可执行jar包结构挑选经典的springboot启动包来做示范:
|-- _jar包根目录|-- _BOOT-INF|-- _classes|-- 原项目class文件和resource文件|-- _lib|--原项目依赖的jar库文件|-- _META-INF|-- MANIFEST.MF|-- spring-configuration-metadata.json(springboot项目特有)|-- build-info.properties|-- _maven|-- _项目目录|-- pom.properties|-- pom.xml
上一节我们得知了如果在MANIFEST.MF中没有Main-Class属性,使用java -jar命令执行jar包会报错,接下来看看在可执行jar包的结构,MANIFEST.MF中具体有什么属性:
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Implementation-Title: XXXX
Implementation-Version: 1.0-SNAPSHOT
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.1.6.RELEASE
Created-By: Maven Archiver 3.4.0
Start-Class: XXX.XXX.XXX.XXXX
Main-Class: org.springframework.boot.loader.JarLauncher
里面有两个很重要的属性:Start-Class和Main-Class,其中Start-Class指的是项目中springboot的SpringApplication启动类,而Main-Class则是jar包的启动类入口。
3. spring-boot-maven-plugin插件打包

springboot打包插件执行原理:
- 读取原jar包:Maven插件都能读
MavenProject对象内容,从中可以读取到Artifact信息,调用该对象的getFile()方法即可获取原jar包文件对象; - 读取项目依赖jar库:直接使用
MavenProject对象的getArtifacts()方法即可获取依赖的jar库; - 加载
launchScript:读取embeddedLaunchScript配置,并构建LaunchScript对象; - 重新改写
MANIFEST.MF:到此步骤开始为repackage的核心流程,改写清单文件时最主要的便是写入Start-Class和Main-Class属性,除此之外还会写入jar库和原项目文件目录属性; - 写入
spring-boot-loader包文件:该包是springboot对接java -jar执行命令的核心处理逻辑,springboot打包后加入的Main-Class: org.springframework.boot.loader.JarLauncher属性指向的类便是此包中的jar包启动类,如果war包则会写入war包启动类; - 写入原项目文件:原项目文件会被挪到
BOOT-INF/classes/目录下; - 写入项目依赖jar库:原项目依赖的jar库会被写入到
BOOT-INF/lib/目录下。
如果要看spring-boot-maven-plugin插件打包源码以分析原理,可导入插件的依赖,此时就能看到该插件的源码。如果使用的是IDEA,下载源码后打上断点,在执行package时,使用debug模式启动也能直接进行调试。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>XXXXX</version>
</dependency>
4. 执行jar原理
将会分析执行java -jar命令后,Java程序调用到Springboot启动类main方法的流程。

- JVM启动,执行加载主函数
LoadMainClass:此时是在JVM底层实现的,里面指定了LauncherHelper类; - 执行
LauncherHelper的checkAndLoadMain方法:JVM将会调用LauncherHelper的checkAndLoadMain方法,解析并校验jar包,并获取主要的启动类; - 解析jar的
MANIFEST.MF文件:在此方法中会完成读取MANIFEST.MF文件,主要是读取其中的Main-Class属性,并做jar包启动的校验; GetStaticMethodID方法:JVM获取到Main-Class类对象,调用Main-Class类对象的main方法;- 执行
JarLauncher的main方法:JarLauncher继承自Launcher,main方法最后还是会调用到Launcher.launch()方法中; - 读取jar的
Start-Class:此时会读取jar包的Start-Class属性,该属性就是原项目的SpringApplication启动类; - 调用启动类的main方法:调用MainMethodRunner的run方法,里面会调用Start-Class类的main方法
- 此时调入到自定义的启动类中,完成启动Springboot程序的入口程序。
相关文章:
spring-boot-maven-plugin插件打包和java -jar命令执行原理
文章目录 1. Maven生命周期2. jar包结构2.1 不可执jar包结构2.2 可执行jar包结构 3. spring-boot-maven-plugin插件打包4. 执行jar原理 1. Maven生命周期 Maven的生命周期有三种: clean:清除项目构建数据,较为简单,不深入探讨&a…...
Python办公自动化教程(001):PDF内容提取
1、Pdfplumber介绍 pdfplumber的github地址: https://github.com/jsvine/pdfplumber/【介绍】:pdfplumber 是一个用于处理 PDF 文件的 Python 第三方库,它提供了一种方便的方式来提取 PDF 文件中的文本、表格和其他信息。【功能】ÿ…...
HarmonyOS鸿蒙开发实战(5.0)自定义全局弹窗实践
鸿蒙HarmonyOS开发实战往期文章必看: HarmonyOS NEXT应用开发性能实践总结 最新版!“非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线!(从零基础入门到精通) 非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线&am…...
【AI学习】了解OpenAI o1背后的self-play RL:开启新的智能道路
在ChatGPT刚刚出来的时候,沐神关于ChatGPT有一段视频,只有几分钟,却是讲得极其透彻的一段。大概意思就是,过去的AI智能水平,比如五年前,大概相当于人类5秒钟思考的程度,包括自动驾驶,…...
Java项目实战II基于Java+Spring Boot+MySQL的车辆管理系统(开发文档+源码+数据库)
目录 一、前言 二、技术介绍 三、系统实现 四、论文参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 "随着…...
IPsec-VPN中文解释
网络括谱图 IPSec-VPN 配置思路 1 配置IP地址 FWA:IP地址的配置 [FW1000-A]interface GigabitEthernet 1/0/0 [FW1000-A-GigabitEthernet1/0/0]ip address 10.1.1.1 24 //配置IP地址 [FW1000-A]interface GigabitEthernet 1/0/2 [FW1000-A-GigabitEthernet1/0/2]ip a…...
Ubuntu 22.04 源码下载、编译
Kernel/BuildYourOwnKernel - Ubuntu Wikihttps://wiki.ubuntu.com/Kernel/BuildYourOwnKernel 一、查询当前系统内核版本 rootubuntu22:~# uname -r 5.15.0-118-generic 二、查询本地软件包数据库中的内核源码信息 rootubuntu22:~# apt search linux-source Sorting... Do…...
【深度学习实战—11】:基于Pytorch实现谷歌QuickDraw数据集的下载、解析、格式转换、DDP分布式训练、测试
✨博客主页:王乐予🎈 ✨年轻人要:Living for the moment(活在当下)!💪 🏆推荐专栏:【图像处理】【千锤百炼Python】【深度学习】【排序算法】 目录 😺〇、仓库…...
基于SpringBoot+WebSocket实现地图上绘制车辆实时运动轨迹图
实现基于北斗卫星的车辆定位和轨迹图的Maven工程(使用模拟数据),我们将使用以下技术: Spring Boot:作为后端框架,用来提供数据接口。Thymeleaf:作为前端模板引擎,呈现网页。Leaflet…...
嵌入式入门小工程
此代码基于s3c2440 1.点灯 //led.c void init_led(void) {unsigned int t;t GPBCON;t & ~((3 << 10) | (3 << 12) | (3 << 14) | (3 << 16));t | (1 << 10) | (1 << 12) | (1 << 14) | (1 << 16);GPBCON t; }void le…...
hackmyvm靶场--zon
环境 攻击机kali 靶机 未知 主机探测 因为在同一个局域网内使用ARP协议探测存活主机 靶机为192.168.56.128 端口探测 常见的80和22端口 那么一定是寻找web漏洞拿shell了 后台扫描 后台扫描常用dirsearch和gobuster,有时候小字典可能不太行,可以尝试换个大点…...
atcoder abc372 启发式合并, dp
A delete 代码: #include <bits.stdc.h>using namespace std;int main() {string s;cin >> s;for(auto t: s) if(t ! .) cout << t; } B 3 ^ A 思路:三进制转换,可以参考二进制,先把当前可以加入的最大的3的…...
CentOS Stream 9部署MariaDB
1、更新系统软件包 sudo dnf update 2、安装MariaDB软件包(替代mysql) sudo dnf install mariadb-server 3、安装MariaDB服务 sudo systemctl enable --now mariadb 4、检查MariaDB服务状态 sudo systemctl status mariadb 5、配置MariaDB安全性 sudo my…...
【Leetcode:997. 找到小镇的法官 + 入度出度】
🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...
大数据Flink(一百二十三):五分钟上手Flink MySQL连接器
文章目录 五分钟上手Flink MySQL连接器 一、创建数据库表 二、创建session集群 三、源表查询 四、窗口计算 五、结果数据写回数据库 五分钟上手Flink MySQL连接器 MySQL Connector可以将本地或远程的MySQL数据库连接到Flink中&#x…...
SYN Flood攻击原理,SYN Cookie算法
SYN Flood是一种非常危险而常见的Dos攻击方式。到目前为止,能够有效防范SYN Flood攻击的手段并不多,SYN Cookie就是其中最著名的一种。 1. SYN Flood攻击原理 SYN Flood攻击是一种典型的拒绝服务(Denial of Service)攻击。所谓的拒绝服务攻击就是通过进…...
计组(蒋)期末速成笔记1
蒋本珊计组期末不挂科复习笔记 第1章 概论 第2章 数据的机器层次表示 第3章 指令系统 第4章 数值的机器运算 第5章 存储系统和结构 第6章 中央处理器 第7章 总线 第1章 概论 蒋本珊计组期末不挂科复习笔记知道你快考试了,莫慌! 第1章 概论1.1 冯诺依曼计…...
mysql学习教程,从入门到精通,SQL 更新数据(UPDATE 语句)(17)
1、SQL 更新数据(UPDATE 语句) SQL UPDATE 需要指定要更新的表、要修改的列以及新值,并且通常会通过WHERE子句来指定哪些行需要被更新。下面是一个简单的示例,说明如何使用UPDATE语句。 假设我们有一个名为employees的表…...
【吊打面试官系列-MySQL面试题】MyISAM 表格将在哪里存储,并且还提供其存储格式?
大家好,我是锋哥。今天分享关于【MyISAM 表格将在哪里存储,并且还提供其存储格式?】面试题,希望对大家有帮助; MyISAM 表格将在哪里存储,并且还提供其存储格式? 每个 MyISAM 表格以三种格式存储…...
常用的图像增强的算法之间的联系和区别
Unsharp Mask (USM)、拉普拉斯算子、直方图均衡化和伽马增强是图像处理中常见的技术,但它们在原理、作用和应用场景上有显著不同。以下是对这些方法的详细比较: 1. Unsharp Mask (USM) 原理:USM 是通过对图像进行模糊处理(如高斯…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
