啥?你没听过SpringBoot的FatJar?

写在最前面:

 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.mzph.cn/diannao/42037.shtml

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

相关文章

robotframework-appiumLibrary 应用 - 实现 app 自动化

1、安装appiumLibrary第三方库 运行pip命令:pip install robotframework-appiumlibrary 若已安装,需要更新版本可以用命令:pip install -U robotframework-appiumlibrary 2、安装app自动化环境。 参考我的另外一篇专门app自动化环境安装的…

设计模式探索:策略模式

1. 什么是策略模式(Strategy Pattern) 定义 策略模式(Strategy Pattern)的原始定义是:定义一系列算法,将每一个算法封装起来,并使它们可以相互替换。策略模式让算法可以独立于使用它的客户端而…

打卡第4天----链表

通过学习基础,发现我的基本功还得需要再练练,思路得再更加清晰明了,这样子做算法题才能驾轻就熟。每天记录自己的进步。 一、两两交换 题目编号:24 题目描述: 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本…

[数据结构] 基于交换的排序 冒泡排序快速排序

标题:[数据结构] 基于交换的排序 冒泡排序&&快速排序 水墨不写bug (图片来源于网络) 目录 (一)冒泡排序 优化后实现: (二)快速排序 I、实现方法: &#…

opencv环境搭建-python

最近遇到了一些图像处理的需求,所以需要学习一下opencv,来记录一下我的学习历程。 安装numpy pip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy安装matplotlib pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib安装opencv …

ctfshow web入门 web338--web344

web338 原型链污染 comman.js module.exports {copy:copy };function copy(object1, object2){for (let key in object2) {if (key in object2 && key in object1) {copy(object1[key], object2[key])} else {object1[key] object2[key]}}}login.js var express …

gcc/g++的四步编译

目录 前言1.预处理(进行宏替换)2.编译(生成汇编)3.汇编(生成二进制文件)4. 链接 (生成可执行文件)a. 动态库 && 动态链接b. 静态库 && 静态链接c. 验证d. 动静态链接…

技术实现路径怎么写?(Word项目技术路径文档参考)

软件项目编写技术实现路径至关重要,因为它为项目团队提供了清晰的开发蓝图。这一路径明确了从项目启动到交付各阶段所需的技术方案、步骤及预期成果,有助于团队统一认识,确保开发工作有序进行。同时,技术实现路径有助于识别潜在的…

HetuEngine简介

目录 HetuEngine是什么? HetuEngine的特点以及使用场景 特点 使用场景 HetuEngine介绍 结构 近期用到了Hetu,了解下这个工具是起什么作用的。 HetuEngine是什么? 是引擎,设计是为了让与当前的大数据生态完美融合的引擎&am…

本安防爆手机:危险环境下的安全通信解决方案

在石油化工、煤矿、天然气等危险环境中,通信安全是保障工作人员生命安全和生产顺利进行的关键。防爆智能手机作为专为这些环境设计的通信工具,提供了全方位的安全通信解决方案。 防爆设计与材料: 防爆智能手机采用特殊的防爆结构和材料&…

Mysql部署MHA高可用

部署前准备: mysql-8.0.27下载地址:https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.27-1.el7.x86_64.rpm-bundle.tar mha-manager下载地址:https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-mana…

为什么需要做网络安全服务?

网络安全服务之所以重要,是因为它在保护数字资产、维护企业运营、确保法规遵从、防范恶意行为以及建立信任等方面扮演着关键角色。以下是一些主要的理由: 保护核心资产和数据: 数字化转型使得企业数据变得极其宝贵,包括知识产权、…

深度学习模型加密python版本

支持加密的模型: # torch、torch script、onnx、tensorrt 、torch2trt、tensorflow、tensorflow2tensorrt、paddlepaddle、paddle2tensorrt 深度学习推理模型通常以文件的形式进行保存,相应的推理引擎通过读取模型文件并反序列化即可进行推理过程. 这样一来&#…

20K Stars!一个轻量级的 JS 库

大家好,我是CodeQi! 一位热衷于技术分享的码仔。 Driver.js 是一个轻量级的 JavaScript 库,旨在帮助开发人员创建网站或应用程序的引导和教程。通过 Driver.js,您可以引导用户了解网站的各个功能和使用方式。 Driver.js 提供了高度可定制的功能,使其能够适应各种需求和…

使用Python绘制和弦图

使用Python绘制和弦图 和弦图效果代码 和弦图 和弦图用于展示数据的多对多关系,适合用于社交网络、交通流量等领域的分析。 效果 代码 import pandas as pd import holoviews as hv from holoviews import opts hv.extension(bokeh)# 示例数据 data [(A, B, 2),…

印尼网络安全治理能力观察

在全国国际机场的移民服务完全瘫痪 100 多个小时后,印尼政府承认其新成立的国家数据中心 (PDN) 遭受了网络攻击。 恶意 Lockbit 3.0 勒索软件加密了存储在中心的重要数据,其背后的黑客组织要求支付 800 万美元的赎金。 不幸的是,大多数数据…

性能测试相关理解(一)

根据学习全栈测试博主的课程做的笔记 一、说明 若未特别说明,涉及术语都是jmeter来说,线程数,就是jmeter线程组中的线程数 二、软件性能是什么 1、用户关注:响应时间 2、业务/产品关注:响应时间、支持多少并发数、…

深入解析 androidx.databinding.Bindable 注解

在现代 Android 开发中,数据绑定 (Data Binding) 是一个非常重要的技术。它使得我们能够简化 UI 和业务逻辑之间的连接,从而提高代码的可读性和维护性。在数据绑定中,Bindable 注解是一个关键部分,它帮助我们实现双向数据绑定和自…

【车载开发系列】GIT安装详细教程

【车载开发系列】GIT安装详细教程 【车载开发系列】GIT安装详细教程 【车载开发系列】GIT安装详细教程一. GIT软件概念二. GIT安装步骤三. GIT安装确认三. GIT功能使用1)Git Bash2)Git CMD3)Git FAQs4)Git GUI 一. GIT软件概念 G…

数据库系统原理 | 查询作业1

整理自博主本科《数据库系统原理》专业课自己完成的实验课查询作业,以便各位学习数据库系统概论的小伙伴们参考、学习。 *文中若存在书写不合理的地方,欢迎各位斧正。 专业课本: ​ ———— 本次实验使用到的图形化工具:Heidisql…