啥?你没听过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的启动流程。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数字化精益生产系统--MRP 需求管理系统

MRP(Material Requirements Planning,物料需求计划)需求管理系统是一种在制造业中广泛应用的计划工具,旨在通过分析和计划企业生产和库存需求,优化资源利用,提高生产效率。以下是对MRP需求管理系统的功能设…

[FreeRTOS 功能应用] 事件组 功能应用

文章目录 一、基础知识点二、代码讲解三、结果演示四、代码下载 一、基础知识点 [FreeRTOS 基础知识] 事件组 概念 [FreeRTOS 内部实现] 事件组 本实验是基于STM32F103开发移植FreeRTOS实时操作系统,事件组实战操作。(当task1和task2同时完成,才执行ta…

Python爬虫教程第1篇-基础知识

文章目录 什么是爬虫爬虫的工作原理用途搜索引擎爬虫Robots协议HTTP的请求过程URL的含义HTTP常见请求头爬虫常用的技术 什么是爬虫 信息的交互是通过web网页、或者移动端等不同的客户端端形式进行交互,这个过程是一个人与网路正常的交互行为。而爬虫可以用来模拟人…

easyx图形库

目录 1、绘制简单的图形化窗口 2、设置窗口属性 2.1 颜色设置 2.2 刷新 3、基本绘图函数 3.1 绘制直线 3.2 绘制圆 3.3 绘制矩形 4、贴图 4.1 原样贴图 4.1.1 IMAGE变量去表示图片 4.1.2 加载图片 4.1.3 显示图片 4.2 透明贴图 4.2.1 认识素材 4.3 png贴图 5…

使用块的网络 VGG

一、AlexNet与VGG 1、深度学习追求更深更大,使用VGG将卷积层组合为块 2、VGG块:3*3卷积(pad1,n层,m通道)、2*2最大池化层 二、VGG架构 1、多个VGG块后接全连接层 2、不同次数的重复块得到不同的架构&a…

go语言day10 接口interface 类型断言 type关键字

接口: 空接口类型: 要实现一个接口,就要实现该接口中的所有方法。因为空接口中没有方法,所以自然所有类型都实现了空接口。那么就可以使用空接口类型变量去接受所有类型对象。 类比java,有点像Object类型的概念&#x…

使用Docker、Docker-compose部署单机版达梦数据库(DM8)

安装前准备 Linux Centos7安装:https://blog.csdn.net/andyLyysh/article/details/127248551?spm1001.2014.3001.5502 Docker、Docker-compose安装:https://blog.csdn.net/andyLyysh/article/details/126738190?spm1001.2014.3001.5502 下载DM8镜像 …

数据按月分表

当数据量过大,从数据层面可以按月分表,报表查询时可以根据,查询时间来计算查询的年月,查询对应的表 1、按月分表: 存储过程SP_BRANCH_TABLE_TEST 以下存储过程分表,加了索引可以方便后续查询 USE [DASHBOAR…

三分钟内了解卷轴模式

在数字化时代的浪潮中,卷轴商业模式巧妙地将积分体系、互动任务、社交裂变、虚拟经济体系以及个性化成长路径等多元要素融为一体。 积分体系:激发参与动力的源泉 卷轴商业模式的核心在于其精心构建的积分系统。新用户踏入平台,即获赠一笔启…

Windows上Docker的安装与初体验

Docker Desktop下载地址 国内下载地址 一、基本使用 1. 运行官方体验镜像 docker run -d -p 80:80 docker/getting-started执行成功 停止体验服务 docker stop docker/getting-started删除体验镜像 docker rmi docker/getting-started2. 修改docker镜像的存储位置 3. …

vofa+:一款超级好用的可视化串口调试软件

目录 一、软件配置 1、先配置好usart1串口 2、重定向printf: 3&#xff0c;勾选魔术棒中的LIB 二、vofa的使用 1、RawData模式 2、FireWater 一、软件配置 1、先配置好usart1串口 2、重定向printf: 在 stm32f4xx_hal.c中添加&#xff1a; #include <stdio.h> e…

【nvm管理nodejs版本,切换node指定版本】

nvm管理nodejs版本 nvm管理nodejs版本主要功能使用 nvm nvm管理nodejs版本 nvm&#xff08;Node Version Manager&#xff09;顾名思义node版本管理器&#xff0c;无须去node管网下载很多node安装程序;用于管理多个 Node.js 版本的工具。它允许你在同一台机器上同时安装和管理…

文件上传(本地、OSS)

什么是文件上传&#xff1a;将文件上传到服务器。 文件上传-本地存储 前端 <template> <div><!-- 上传文件需要设置表单的提交方式为post&#xff0c;并设置enctype属性、表单项的type属性设置为file --><form action"http://localhost:8080/wedu/…

使用Python绘制和弦图

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

价格预言机的使用总结(一):Chainlink篇

文章首发于公众号&#xff1a;Keegan小钢 前言 价格预言机已经成为了 DeFi 中不可获取的基础设施&#xff0c;很多 DeFi 应用都需要从价格预言机来获取稳定可信的价格数据&#xff0c;包括借贷协议 Compound、AAVE、Liquity &#xff0c;也包括衍生品交易所 dYdX、PERP 等等。…

vb.netcad二开自学笔记1:万里长征第一步Hello CAD!

已入门的朋友请绕行&#xff01; 今天开启自学vb.net 开发autocad&#xff0c;网上相关资料太少了、太老了。花钱买课吧&#xff0c;穷&#xff01;又舍不得&#xff0c;咬牙从小白开始摸索自学吧&#xff0c;虽然注定是踏上了一条艰苦之路&#xff0c;顺便作个自学笔记备忘!积…

网络安全领域国标分类汇总大全V1.0版:共计425份标准文档,全部可免费下载

《网络安全法》、《数据安全法》、《个人信息保护法》落地实施需要大量国家标准的支撑&#xff0c;博主耗时三周时间&#xff0c;吐血整理了从1999年至今相关的所有涉及安全的国家标准&#xff0c;梳理出《网络安全领域国标分类汇总大全V1.0版》&#xff0c;共计 425 项现行标准…

深度解析 Raft 分布式一致性协议

本文参考转载至&#xff1a;浅谈 Raft 分布式一致性协议&#xff5c;图解 Raft - 白泽来了 - 博客园 (cnblogs.com) 深度解析 Raft 分布式一致性协议 - 掘金 (juejin.cn) raft-zh_cn/raft-zh_cn.md at master maemual/raft-zh_cn (github.com) 本篇文章将模拟一个KV数据读写服…

ShardingSphere实战

ShardingSphere实战 文章目录 ShardingSphere实战分库分表实战建表建表sql利用存储过程建表Sharding-jdbc分库分表配置 基于业务的Sharding-key考虑订单id用户id分片策略订单id的设计与实现**设计思想**&#xff1a;设计思路&#xff1a; 具体分片策略实现测试数据插入商户商品…

【pyqt-实训训练】串口助手

串口助手 前言一、ui设计二、ui的控件命名三、ui转py使用类的方法【扩展】使用ui文件导入&#xff01;P7的小错误解决办法 总结 前言 我的惯例就是万物之始&#xff0c;拜见吾师&#x1f970;⇨pyqt串口合集 最开始的时候我想的是&#xff0c;学了那么久的pyqt&#xff0c;我…