为什么springboot的jar可以直接启动

news/2025/4/19 3:37:00/文章来源:https://www.cnblogs.com/MaC-Matthew/p/18790510

一、讲述
1.SpringBoot提供了一个插件spring-boot-maven-plugin用于把程序打包成一个可执行的jar包。

2.Spring Boot应用打包之后,生成一个Fat jar(jar包中包含jar),包含了应用依赖的jar包和Spring Boot loader相关的
类。

3.java -jar会去找jar中的manifest文件,在那里面找到真正的启动类(Main-Class);

4.Fat jar的启动Main函数是JarLauncher,它负责创建一个LaunchedURLClassLoader来加载boot-lib下面的jar,并以一个新线程启动应用的启动类的Main函数(找到manifest中的Start-Class)。

二、原理
SpringBoot提供了一个插件spring-boot-maven-plugin用于把程序打包成一个可执行的jar包。pom文件配置如下

<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version>
</plugin>

插件spring-boot-maven-plugin,提供了7个maven goal

  • build-image: 将程序使用 buildpack 打包进容器镜像中。
  • build-info:生成项目的构建信息文件 build-info.properties
  • help:显示帮助信息。调用mvn spring-boot:help -Ddetail=true -Dgoal=以显示参数详细信息。
  • repackage:可生成可执行的jar包或war包。插件的核心goal。
  • run:运行 Spring Boot 应用
  • start:在集成测试阶段,控制生命周期
  • stop:在集成测试阶段,控制生命周期

2、通过mvn package命令,Maven首先会按照标准流程构建项目,随后spring-boot-maven-plugin会执行repackage目标,该目标会重新包装已生成的标准JAR文件,将其转换为包含所有依赖项和适当的启动器信息的Fat JAR。这样生成的JAR可以直接通过java -jar命令启动。jar内部目录如下

  • META-INF/: 包含MANIFEST.MF文件和其他元数据信息,其中Main-Class属性指向Spring Boot的启动类加载器。
  • BOOT-INF/classes/: 存放项目自身的类文件和资源文件。
  • BOOT-INF/lib/: 放置所有依赖的jar包,包括Spring Boot starter依赖以及其他第三方库。(如果项目中有静态资源文件,也会在BOOT-INF下有对应的static、templates等目录)

3、Spring Boot启动器与Loader机制与MANIFEST.MF文件
Spring Boot应用的jar包可以直接运行主要依赖于它的启动器以及Loader机制,而对于Loader机制主要利用MANIFEST.MF文件以及其内部类加载逻辑。

MANIFEST.MF是JAR文件内的一个标准元数据文件,它包含了关于JAR包的基本信息和运行指令。在jvm规范单中java -jar指令中会规范一个main方法,而这个main方法就在MANIFEST.MF文件中的Main-Class属性,这个类通常是org.springframework.boot.loader.JarLauncher或其他由Spring Boot提供的启动器类。Start-Class属性是启动应用的main方法。JarLauncher会通过一个子线程启动Start-Class中的main方法

4、JarLauncher执行流程

JarLauncher 入口 main 方法

public static void main(String[] args) throws Exception {// launch 方法是调用父类 Launcher 的 launch 方法new JarLauncher().launch(args);
}

这里是加载清单文件的中的配置

   /*** Launch the application. This method is the initial entry point that should be* called by a subclass {@code public static void main(String[] args)} method.启动一个应用,这个方法应该被初始的入口点,这个入口点应该是一个Launcher的子类的 public static void main(String[] args)这样的方法调用* @param args the incoming arguments* @throws Exception if the application fails to launch*/protected void launch(String[] args) throws Exception {if (!isExploded()) {// 注册一些 URL的属性JarFile.registerUrlProtocolHandler();}// 创建类加载器(LaunchedURLClassLoader),加载得到集合要么是BOOT-INF/classes/,或者BOOT-INF/lib/的目录或者是他们下边的class文件或者jar依赖文件ClassLoader classLoader = createClassLoader(getClassPathArchivesIterator());String jarMode = System.getProperty("jarmode");String launchClass = (jarMode != null && !jarMode.isEmpty()) ? JAR_MODE_LAUNCHER : getMainClass();// 执行应用的main方法launch(args, launchClass, classLoader);}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

折腾笔记[17]-使用rust创建linux系统服务

使用rust内嵌配置文件, 创建新用户并创建linux的service服务;实现后台服务循环打印时间到`/tmp/log_file_service`. Use Rust to embed configuration files, create new users, and create service services for Systemd; Implement a backend service loop to print time to …

[PNPM] 其他包管理器

Yarn Yarn 这个包管理器是在 2016 的时候由 Facebook、Google、Exponent 以及 Tilde 团队共同开发推出的。当时 Yarn 的出现主要是为了解决 npm 在速度、安全性以及一致性方面的一些问题:安装速度确定性:项目A ---> 直接依赖: libraryX(1.0)-----> 间接依赖:librar…

3.24 位运算,哈希,前缀

题目链接 题目背景 我们需要解决的问题是:给定一个整数数组 nums 和两个整数 low 和 high,统计满足条件的“漂亮数对” (i, j) 的数量,其中: 0 <= i < j < nums.length low <= (nums[i] XOR nums[j]) <= high 简单来说,我们要找所有满足条件的数对 (i, j),…

Kioptrix Level_1

Kioptrix Level 1.1 靶场配置 导入靶场时先将vmx后缀文件中的带有ethernet0的配置行全部删除,再导入靶场,添加一个网络适配器即可 信息收集 查找目标主机ip ┌──(root㉿kali)-[~] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:84:b2:cc, IPv4: 192.168…

selenium之八大定位

八大定位 今天我们来学一学,selenium有名的八大定位方式;都有哪八个呢,下面我先列出来;之后再一个一个的实践id,通过id定位元素 name,通过name定位 class_name,通过class类名定位 tag_name,通过标签名称 link_text,通过链接文本 partial_link_text,通过部分链接文本 …

NAS配置iCloudpd

附上链接【教程】使用icloudpd自动同步iCloud照片 纠正两个错误: 1)sync-icloud.sh --Initialise 原文写的是sync-icloud.sh –Initialise是错误的,现在的版本应该如上 需要-- 不然你就会反复出现2分钟后重试的问题 2)文中的 *** 这步很重要!!!成功后,你会发现 config …

滴滴数据仓库工程师面试题

‌一、数据仓库基础与建模‌‌数仓分层设计‌请描述滴滴数仓分层架构及各层核心作用(如ODS、DWD、DWS、ADS)‌。 ‌1. ODS(Operational Data Store)层:原始数据层‌‌数据内容‌:直接从业务系统抽取的原始数据,包括订单流水、用户行为日志、司机接单记录、GPS轨迹等。‌…

20244209韩仕炜《Python程序设计》实验一报告

课程:《Python程序设计》 班级: 2442 姓名:韩仕炜 实验教师:王志强 学号:20244209 实验日期:2025年3月24日 必修/选修:专选课 1. 实验内容 1.熟悉Python开发环境; 2.练习Python运行、调试技能; 3.编写程序,练习变量和类型、字符串、对象、缩进和注释等; 4.编写一…