啥?你没听过SpringBoot的FatJar?

news2024/11/19 2:32:50

写在最前面:

 SpringBoot是目前企业里最流行的框架之一,SpringBoot的部署方式多数采用jar包形式。通常,我们使用java -jar便可以直接运行jar文件。普通的jar只包含当前 jar的信息,当内部依赖第三方jar时,直接运行则会报错,但是,SpringBoot所打成的jar包,却可以直接部署运行。今日,小白不黑带大家来探讨一下---SpringBoot的启动原理。

 通过本篇文章,各位看官可以了解到:

  •     SpringBoot的启动过程

  •    SpringBoot的FatJar技术

  •    类加载器的使用

话不多说,开工!

大家都知道,SpringBoot的入口是启动类的main方法,这是正确的,但也不是完全正确。我们可以简单了解一下,看看run方法里面做了什么事情。废话不多说,先上时序图

再来一张源码图!

PS:从时序图中可以看到,可以通过实现ApplicationRunner/CommandLineRunner方法就可以在SpringBoot启动完成后,做一些自定义的事情

看到这里,估计大家都会对SpringBoot启动流程有一个大概的认识。对于更深入的了解,有兴趣的小伙伴可以直接看SpringBoot启动类源码。

好的,收工,下班!

你以为这样就结束了?No!NoNo,这并不是我今天所要讲的,让我们把维度再往上拉一层,我们的SpringBoot项目的main方法是如何被执行的?

 众所周知,我们的SpringBoot项目都是通过java -jar运行的,不知道大家是否想过一个问题,java -jar就可以运行整个SpringBoot应用,那么,该项目依赖的jar包是如何被加载的呢?

这就涉及到SpringBoot的FatJar设计了。所谓FatJar,其实就是SpringBoot的一个jar包。对于SpringBoot的可运行jar包,其实是包含了项目所有依赖的,这种打包方式归功于SpringBoot的一个打包插件spring-boot-maven-plugin。这玩意就相当于是一个拦截器,在maven package后,将maven 打成的jar包变成fatJar,并保留原来的jar包为xx.original。各位看官,请看图!

PS:spring-boot-maven-plugin需要引入spring-boot-starter-parent才会生成fatjar(实践出真知)

好了,讲了那么久fatjar,那么,FarJar究竟长啥样呢?各位看官,请再看图

PS:BOOT-INF:存放业务代码以及相关的依赖jar包META-INF:这个文件极其重要,里面存放了SpringBoot项目的元信息,包括主类信息,依赖信息,类路径信息等
org.springframework.boot.loader:SpringBoot自带的代码,用来启动springboot项目,调用我们业务代码中的main方法

ok,现在让我们来分析一下META-INF这个文件几个重要的信息

  •  Implementation-Ttitle:项目名称

  • Main-Class:SpringBoot程序真正的启动类

  • Start-Class:平时业务代码中的启动类

  • Spring-Boot-Lib:依赖的jar包路径

SpringBoot通过Meta-INF清单文件,就可以解析到整个SpringBoot项目的信息,便可以找到对应的入口程序,启动SpringBoot项目。

来到这里,我们再思考一下,对于java -jar命令,只会执行主类的main方法。让我们看看这个main方法,是如何启动springBoot项目的。

首先,看到JarLuncher()有个main方法,该方法创建了一个JarLauncher实例,并调用其launch方法,让我们点进去一探究竟

 可以看到,launch()方法,先是创建了一个类加载器,然后获取主类,实际拿的是META-INF下的start-class,再调用重载方法launch(),执行start-class。而这个类加载器,就是LaunchedURLClassLoader。该类加载器可以加载指定路径下的类,如lib文件夹的jar包。

 让我们再看看重载方法lunch()方法的实现,该实现首先将LaunchedURLClassLoader设置为线程的上下文类加载器,然后调用createMainMethodRunner方法。

由此可以分析出,SpringBoot的加载,是打破了双亲委派机制的。因为ThreadContextClassLoader的存在,就是为了打破双亲委派机制。

那么,问题来了,ThreadContextClassLoader是如何打破双亲委派的呢?

只需要在被父ClassLoader加载的类中,使用ContextClassLoader去加载其无法加载的类即可。另外,创建线程的时候,设置一下当前线程的ContextClassLoader便可。而普通线程池里面,默认的线程工厂在创建线程时,会默认继承父线程的线程上下文类加载器。

PS:之所以要打破双亲委派,原因之一是需要底层的类加载器,委托上层的类加载器去加载自定义的类。

让我们来看看createMainMethodRunner的最终实现。

 首先,该方法通过类加载器Class.forName将启动类(Start-class)加载进内存,然后通过反射,调用其main方法。也就是最终我们业务代码中的main方法。

至此,SpringBoot便从业务代码的启动类开启,初始化各种组件,完成SpringBoot的启动流程。

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

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

相关文章

Python 空间和时间高效的二项式系数(Space and time efficient Binomial Coefficient)

这里函数采用两个参数n和k,并返回二项式系数 C(n, k) 的值。 例子: 输入: n 4 和 k 2 输出: 6 解释: 4 C 2 等于 4!/(2!*2!) 6 输入: n 5 和 k 2 输出: 10 解释: 5 C …

关于GIS的概念方面在前端编程中的理解

关于GIS的概念方面在前端编程中的理解 一. 什么是gis二. 关于地球的建模(了解)三. GIS坐标系表现形式四.GIS的数据4.1 矢量数据4.2 栅格数据4.3 矢量数据和栅格数据的不同 一. 什么是gis 地理坐标系统,其目的就是通过地理坐标系可以确定地球上任何一点的位置。 二. …

springboot网吧信息管理系统-计算机毕业设计源码31030

目录 摘要 1 绪论 1.1 选题背景与意义 1.2国内外研究现状 1.3 本课题主要工作 1.4论文结构与章节安排 2系统分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统流程分析 2.2.1 数据新增流程 2.2.2 数据删除流程 2.3 系统功能分析 2.…

YOLO之boxes小记

import cv2 from ultralytics import YOLO # 加载模型 model YOLO(modelyolov8n.pt) results model(sourceanimal.jpg)result results[0] img result.plot() from matplotlib import pyplot as plt # matplotlib :rgb模式 # cv:bgr模式 plt.imshow(Ximg[:,:,::-1])result.b…

海睿思问数(TableGPT):开创企业新一代指标应用模式

1 指标建设对企业经营管理数字化的价值分析 指标是将海量数据中关键信息提炼和挖掘出来,以数据为载体展示企业经营管理和分析中的统计量。它通过分析数据,形成一个具有度量值的汇总结果,使得业务状态可以被描述、量化和分解。指标通常由度量…

【记录】如何使用IDEA2023

前言: 记录IDEA2023的激活与安装 第一步:官网下载安装包: 下载地址:https://www.jetbrains.com/idea/download/other.html 这个最好选择2023版本,用着很nice。 安装步骤就不详解了,无脑下一步就可以了…

上位机图像处理和嵌入式模块部署(mcu项目1:用户手册)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 一个完整的产品,除了上位机软件、固件、硬件、包装之外,一般还需要一个用户手册。好的用户手册应该能够兼顾到大多数人的认…

Java数据结构-树的面试题

目录 一.谈谈树的种类 二.红黑树如何实现 三.二叉树的题目 1.求一个二叉树的高度,有两种方法。 2.寻找二叉搜索树当中第K大的值 3、查找与根节点距离K的节点 4.二叉树两个结点的公共最近公共祖先 本专栏全是博主自己收集的面试题,仅可参考&#xf…

强技能 展风采 促提升——北京市大兴区餐饮行业职工技能竞赛精彩呈现

6月19日,由大兴区总工会、区商务局、青云店镇人民政府联合主办,区服务工会、区餐饮行业协会承办的“传承中国技艺,打造新一代餐饮工匠”2024年大兴区餐饮行业职工职业技能竞赛决赛在北京华联创新学习中心隆重开幕。区总工会副主席郝泽宏&…

运维锅总详解计算机存储

本文从计算机存储简介、存储设备介绍、软件定义存储(SDS)、常见的Kubernetes CSI存储插件介绍、如何平衡成本和存储性能等方面对计算机存储进行详细分析;本文最后还通过图形展示了存储在计算机体系结构中的重要作用。希望对您有所帮助! 一、计算机存储简…

沉浸式三维园区场景漫游体验

利用图扑三维可视化技术展示园区在不同时间段的变化,提供全景漫游体验,帮助用户全方位感受和理解园区环境,实现智能化管理与优化。

昇思第10天

RNN实现情感分类 二分类问题:Positive和Negative两类 步骤: 1.加载IMDB数据集 2.加载预训练词向量:预训练词向量是对输入单词的数值化表示,通过nn.Embedding层,采用查表的方式,输入单词对应词表中的index,…

OPENCV(图像入门笔记)

使用OpenCV读取图像 使用cv.imread()函数读取图像。 第一个参数为图像名称 第二个参数是一个标志,它指定了读取图像的方式。分别有三种 cv.IMREAD_COLOR: 加载彩色图像。任何图像的透明度都会被忽视。它是默认标志。 cv.IMREAD_GRAYSCALE:以…

武汉免费 【FPGA实战训练】 Vivado入门与设计师资课程

一.背景介绍 当今高度数字化和智能化的工业领域,对高效、灵活且可靠的技术解决方案的需求日益迫切。随着工业 4.0 时代的到来,工业生产过程正经历着前所未有的变革,从传统的机械化、自动化逐步迈向智能化和信息化。在这一背景下&…

windows USB 设备驱动开发-控制传输的数据包

每次在主机控制器和 USB 设备之间移动数据时,都会发生传输。 通常,USB 传输可大致分为控制传输和数据传输。 所有 USB 设备都必须支持控制传输,并且可以支持用于数据传输的端点。 每种类型的传输都与设备缓冲区USB 端点 的类型相关联。 控制传…

vscode远程连接linux(配置免密)

远程连接 1.首先保证物理机和虚拟机网络可以ping通 2.查看ubuntu得ip地址 ifconfig IP为:192.168.52.133 3.连接远程主机 配置免密 1.打开cmd运行ssh-keygen -t rsa 一路回车就行 2.打开window文件夹C:\Users\xbj\.ssh 3.用记事本打开id_rsa.pub文件复制公…

没有tpm2.0,你就不打算升级win11?屁孩君小白式教学如何跳过

屁孩君终于回归了,回归首文 博主的姥爷电脑已用此方法成功 目录 屁孩君终于回归了,回归首文下载win11镜像将镜像进行提取删除检测文件断网,防止windows重新补全检测文件点击setup,进行检测安装 完成屁孩君终于回归了,记…

idea使用技巧---超实用的mybatisX插件

一、使用原因 传统创建mybatis项目之后,在mapper接口和xml映射文件之间手动切换非常麻烦:不仅需要记住文件的所在位置,而且每次在mapper当中添加一个新的接口,都需要单独手动点开xml再编写sql; eg:在item…

CSS中 实现四角边框效果

效果图 关键代码 border-radius:10rpx ;background: linear-gradient(#fff, #fff) left top,linear-gradient(#fff, #fff) left top,linear-gradient(#fff, #fff) right top,linear-gradient(#fff, #fff) right top,linear-gradient(#fff, #fff) left bottom,linear-gradient(…

多模态MLLM都是怎么实现的(11)--从SadTalker到快手LivePortait

我之前出差带休假差不多两个礼拜吧,今天回北京更新一篇 我确实找到了一个有意思的东西,LivePortrait 这东西开源了,你可以认为是目前做得最好的"Sadtalker",国内也有dream-talker,EMO之类的。 我之前看EMO的…