SpringBoot: 启动流程和类装载

深入解析Spring Boot项目的类加载与启动流程 Spring Boot 是当今 Java 开发中最流行的框架之一,其“约定优于配置”的理念大大简化了应用程序的开发过程。然而,Spring Boot 的启动过程涉及诸多底层机制,其中类加载与启动流程是理解 Spring Boot 内部原理的核心。本文将全面解析 Spring Boot 项目的类加载与启动流程,帮助开发者深入理解 Spring Boot 的启动机制。 阅读详情

前面我们学过Spring定制了自己的可执行jar,将真正执行时需要的类和依赖放到BOOT-INF/classes、BOOT-INF/lib来,为了能够识别这些为止的源文件,Spring定制了自己类加载器,本节我们来讲解这个类加载器。本节涉及的内容主要包括:

  1. SpringBoot启动流程
  2. SpringBoot类加载器

1. SpringBoot启动流程

在SpringBoot的可执行jar中,配置了MANIFEST.MF的Main-Class设置为JarLauncher,JarLauncher的加载过程如下图

  1. 调用Launcher.launch方法,开始引导程序
  2. 通过Handlers.reigster()注册URLStreamHandler的jar协议处理类,支持getResource读取BOOT-INF/下的内容
  3. 通过archive.getClassPathUrls()筛选可执行jar的所有元素,通过JarLauncher.isIncludedOnClassPath过滤,筛选出所有ClassPath元素
  4. 用这些筛选的ClassPath创建LaunchedClassLoader
  5. 使用LaunchedClassLoader加载MANIFEST.MF的Start-Class
  6. 反射调用main方法

2. SpringBoot类加载器

使用URLClassLoader加载SpringBoot Jar时不会加载BOOT-INF下的classes、lib的类和依赖包,SpringBoot通过自定义类加载器LaunchedClassLoader解决这个问题。它继承自URLClassLoader。参照SpringBoot的启动流程,我们讲手动使用LaunchedClassLoader加载可执行jar,并尝试引导SpringBoot应用。

1. 创建Archive

从启动流程可以看到,核心流程是先通过Archive.getClassPathUrls()获取所有的ClassPath,包括jar文件中内嵌的。JarFileArchive是包可见的,用Archive.create创建实例

URLClassLoader ucl = new URLClassLoader("MyURLClassLoader", new URL[]{url}, null);
Class<?> clazz = ucl.loadClass("org.springframework.boot.loader.JarLauncher");
Archive archive = Archive.create(clazz);
2. 枚举内嵌Jar

Archive提供了getClassPathUrls筛选所有的Archive.Entry,Archive和Archive.Entry可以按JarFile、JarEntry来理解,正是它们有不同的抽象,不仅仅支持jar文件。

Set<URL> su = archive.getClassPathUrls((Archive.Entry e) -> true);
su.stream().forEach(x -> System.out.println(x));

这个方法的输出是这样的,它会是一些jar:nested:协议的URL集合。我们知道URLClassLoader接收一组根路径实现类加载,把这个集合都传递给URLClassLoader是不是就可以了呢?

3. 使用内嵌Jar

讲上一步获取的Set作为根路劲提供给URLClassLoader

URLClassLoader lcl = new URLClassLoader("MyNested", su.toArray(URL[]::new),null);
clazz = lcl.loadClass("com.keyniu.yangsi.YangsiApplication");
System.out.println(clazz);

并不能正常工作,因为jar:nested不是Java支持的内嵌协议

4. 注册协议处理器

在SpringBoot的启动流程里我们专门有提到过Handlers,它就是用来注册协议处理器的在使用3.3.3的代码之前,执行如下代码,就能执行成功了。

Handlers.register();

Handlers.register()实际是通过包名: org.springframework.boot.loader.net.protocol,注册了jar、nested(包名)这两个协议的处理器Handler(对于包下固定类名)

5. 启动SpringBoot

现在我们已经能完整的加载整个SpringBoot可以执行jar了,我们是不是能像JarLauncher一样调用Start-Class的main方法来启动应用呢?答案是肯定的。

private static void testLaunched(URL url) throws Exception {
    URLClassLoader ucl = new URLClassLoader("MyURLClassLoader", new URL[]{url}, null);
    Class<?> clazz = ucl.loadClass("org.springframework.boot.loader.JarLauncher");
    Archive archive = Archive.create(clazz);
    Set<URL> su = archive.getClassPathUrls((Archive.Entry e) -> true);

    Handlers.register();
    su.add(url);

    LaunchedClassLoader lcl = new LaunchedClassLoader(false, su.toArray(URL[]::new), null);

    clazz = Class.forName("com.keyniu.yangsi.YangsiApplication", false, lcl);               // 启动类
    Method mainMethod = clazz.getDeclaredMethod("main", String[].class);
                    // main方法
    mainMethod.setAccessible(true);

    mainMethod.invoke(null, (Object) new String[0]);                                        // 调用main方法
}

5. 参考资料

  1. JVM Specification: Loading、Linking And Initializing,Chapter 5. Loading, Linking, and Initializing
  2. SClass Loaders in Java | Baeldung
springboot当中的类加载器 在 Spring Boot 中,类加载器(ClassLoader)扮演了非常重要的角色,尤其是在应用启动、依赖管理、热部署和模块化等方面。Spring Boot 使用了标准的 Java 类加载机制,但在此基础上进行了扩展和优化,以满足其快速开发和运行的需求。以下是对 Spring Boot 中类加载器的详细介绍:在深入 Spring Boot 的类加载器之前,先回顾一下 Java 中的标准类加载器体系:Spring Boot 构建在 Spring Framework 和嵌入式容器(如 Tomcat、Jett 阅读详情

相关推荐

Spring Boot 类加载机制深度解析

本文深入解析了Spring Boot的类加载机制。首先回顾了Java类加载基础,包括类加载器层次结构和双亲委派模型。然后重点分析了Spring Boot特有的类加载特点,如Fat JAR结构和LaunchedURLClassLoader的实现。文章详细阐述了启动流程中的类加载顺序、优先级,并提供了常见问题的解决方案。最后给出最佳实践和性能优化建议,包括依赖管理、自定义类加载器实现和调试工具使用。对于深入理解Spring Boot运行机制和提高应用性能具有重要参考价值。

ljw714的专栏 1760

核心技术: springboot 启动类加载时方法执行的几种实现方式, bean声明周期, 启动执行顺序

1. 通过实现 InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法2. 通过 元素的 init-method/destroy-method属性指定初始化之后 /销毁之前调用的操作方法3. 方法加@PostConstruct 或@PreDestroy注解 表示是在初始化之后还是销毁之前调用实现一个功能有不同的解决方式, 只有不断的尝试, 探索, 寻找到与当前业务更加贴合的技术, 技术是为业务服务的, 制作不易。

pingzhuyan的博客 3378

SpringBoot启动流程

本文以调试一个实际的SpringBoot启动程序为例,参考流程中主要类类图,来分析其启动逻辑和自动化配置原理。 一、SpringBoot启动流程图 二、SpringBoot启动入口 @EnableScheduling @EnableAsync @SpringBootApplication @EnableAspectJAutoProxy @ComponentScan(basePackages = { "cn.gov.zcy.demand", "cn.gov.zcy.

weixin_64314555的博客 2万+

SpringBoot启动加载过程

SpringBoot与Spring对比 Spring开发过程 通常包括使用Maven、Gradle等工具搭建工程 web.xml定义Spring的DispatcherServlet 完成启动Spring MVC的配置文件 编写响应HTTP请求的Controller以及服务部署到Tomcat Web服务器等步骤 基于传统Spring框架进行开发的开发过于于复杂和繁重的配置工作。 SpringBoot开发特点 编码方面:只需要在maven中添加依赖并实现一个方法就可以提供微服务架构所推荐的RESTful

骑个小蜗牛的博客 3万+

SpringBoot 之启动流程

加载应用程序上下文扫描应用程序中的所有组件自动配置应用程序环境启动嵌入式Web服务器在下面的章节中,我们将逐一分析这些步骤的源代码。在本文中,我们深入分析了 SpringBoot 应用程序的启动过程的源代码。我们了解了 SpringBoot 如何加载应用程序上下文、扫描应用程序中的所有组件、自动配置应用程序环境以及启动嵌入式Web服务器。这些步骤的源代码展示了 SpringBoot 如何简化应用程序的开发和部署。

BASK2312的博客 2757

基于51单片机的多功能智能路灯控制系统(仿真+代码+原理图)

智能路灯控制系统主要由51单片机最小系统+1602显示模块+DS1302时钟模块+光强检测模块+按键输入模块+声光报警模块+LED照明模块+状态检测电路+人体车辆红外检测模块组成。能实现以下功能: 1.能够按键设定系统时间、工作时间、光照阈值 2.工作时间内路灯点亮,凌晨12点后路灯关闭,有人或车通过是,路灯点亮10s 3.非工作时间光照强度低于阈值,路灯点亮 4.能够检测系统工作状态,路灯应亮未亮,声光报警 5.具备手动控制,能够切换自动/手动控制功能

u012759563的博客 8178

SpringBoot启动流程总结

一直很好奇SpringBoot这么一个大怪物,启动的时候做了哪些事情,然后看了很多老师讲的教学视频,然后自己想好好整理一下,做下学习笔记下次也方便自己阅读 1、首先从main方法开始看 public static void main(String[] args) { //代码很简单SpringApplication.run(); SpringApplication.run(Cons...

mnicsm的博客 6万+

RNA 8. SCI文章中差异基因表达--热图 (heatmap) 进阶:从数据标准化到多维度注释

本文深入探讨了RNA差异基因表达分析中热图(heatmap)的进阶应用,从数据标准化到多维度注释。详细介绍了FPKM标准化、Z-score转换等关键技术,以及pheatmap包的高级注释功能,帮助研究者制作发表级热图。文章还提供了视觉优化策略和生物学意义衔接的实用建议,助力SCI论文的数据可视化。

weixin_29051149的博客 302

总结:Springboot启动流程

一、总结 1、关于SpringApplication SpringBoot的启动主要是通过实例化SpringApplication来启动的。 2、实例化SpringApplication时做了什么? SpringApplication的构造方法做了几件事情: 推断WebApplicationType,主要思想就是在当前的classpath下搜索特定的类 搜索META-INF\spring.factories文件配置的ApplicationContextInitializer的实现类 搜索MET

w2009211777的专栏 1万+

Playwright自动化测试实战:攻克日历时间控件三大策略与Java实现

在Web自动化测试领域,元素定位与交互模拟是核心技术基础,其原理在于通过程序精确识别并操作页面中的DOM元素,以模拟真实用户行为。这项技术的核心价值在于提升测试效率、确保交互逻辑的覆盖度与可靠性,广泛应用于电商、金融、OA等系统的功能验证。日历时间控件作为典型的复杂交互组件,常涉及动态弹出层、多级导航与状态同步,是自动化测试中的常见难点。本文聚焦于使用Playwright工具,针对此类控件深入剖析了三种核心解决策略:从最高效的直接赋值、到全面模拟用户交互的主流方法,再到利用组件特性的混合定位方案,并结合Ja

weixin_28835551的博客 311

MFC下使用C++操作Word文档

由于项目需求,在MFC环境下操作将数据和图片写入word文档,之前没有接触过,网上查阅了很多资料,终于把任务完成。理解的不是很透彻,但是这些东西应该够用了,写篇博客记录一下,以便以后再用到。 (1)VS环境下创建一个MFC应用程序,然后在项目上单击右键,选择 类向导-----添加类----类型库中的MFC类。在弹出的对话框中选择文件,位置选择office安装目录下的...

GIS_yuhua的博客 7579

SPRINGBOOT启动流程及其原理

Spring Boot、Spring MVC 和 Spring 有什么区别? 分别描述各自的特征: Spring框架就像一个家族,有众多衍生产品例如boot、security、jpa等等;但他们的基础都是Spring 的ioc和 aop,ioc提供了依赖注入的容器,aop解决了面向切面编程,然后在此两者的基础上实现了其他延伸产品的高级功能。 Spring MV...

u014352080的专栏 3万+

1.3-----Simplify 3D切片软件:从新手困惑到高效打印的进阶设置指南

本文详细介绍了Simplify 3D切片软件在大型模型打印中的高效设置技巧,包括切片效率、支撑结构智能生成和精细参数调节等核心优势。通过实战案例和进阶参数设置指南,帮助用户从新手快速进阶到高效打印,显著提升3D打印质量和效率。

weixin_42552716的博客 422

SpringBoot系列之【启动流程详解】

文章目录前言一、SpringBoot特点二、SpringBoot启动类入口1.注解:@SpringBootApplication@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan2.main方法SpringApplication#run实例化SpringApplication对象SpringApplication.run(java.lang.String...)三、SpringBoot启动事件EventPublishingRunLis

qq_21609191的博客 1万+

基于深度学习的图像修复系统,GAN图像修复,图像修复算法研究,并实现系统登录和注册,全网独发

近年来,深度学习已成为计算机视觉领域的研究热点,基于深度学习的图像修复技术弥补了传统修复方法长期存在的不足,显著提高了生成结果的质量。深度学习是指模仿人脑机制设计的具有深层结构的神经网络。深度学习作为一种表征学习,通过模仿人脑神经元之间的信息传递方式来学习输入数据的特征,并找到输入和输出数据之间的映射关系。通过在图像修复中应用深度学习技术,可以准确学习图像的语义信息,然后根据信息预测缺失的内容,大大克服了传统修复算法的不足,使结果更具逻辑性。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 8266

基于Simulink的超级电容快速响应特性建模与仿真

本文介绍了基于Simulink的超级电容快速响应特性建模与仿真方法。主要内容包括:超级电容的工作原理、一阶RC等效电路模型及其动态电压方程;通过Simulink搭建超级电容模型的两种方法(Simscape Electrical推荐方案和基础模块透明教学方案);仿真100A×100ms放电脉冲下的电压响应特性,并与锂电池进行动态对比;分析超级电容在混合储能系统中的功率分配优势。文章还提供了工程实践要点和扩展方向,如电压均衡、温度影响评估以及与DC-DC变换器集成等。通过建模实践,验证了超级电容在毫秒级响应、高

xiaoheshang_123的博客 98

SpringBoot 启动流程

方法来启动 Spring Boot 应用程序。该方法接受两个参数,第一个参数是启动类的类对象,第二个参数是主方法的参数。方法中做了一系列操作来完成项目启动所需的初始化Spring容器、启动内置tomcat、启动应用程序以及通知监听者等步骤。总的来说,Spring Boot的启动过程是一个复杂的流程,从启动类的Main方法中调用。启动类必须使用 @SpringBootApplication 注解标记该类。方法开始,然后在SpringApplication对象的。方法来执行项目启动的后续操作。

qq_33807380的博客 9554

LPDDR6来了!带你一文看懂它和LPDDR5/5X的差距 + 技术演进逻辑全解析

🧠从速率到架构,从总线宽度到协议设计,LPDDR6 每一个改动都不是拍脑袋做的,它针对的是AI / HPC / 云计算 / 下一代笔记本平台的真实需求。作为工程师的我们,不仅要“用得上”,更要“测得准”,因为没有测试验证,就没有量产落地!🎯LPDDR6不是未来,而是现在进行时!

weixin_43199439的博客 2173

SpringBoot启动原理及相关流程

一、springboot启动原理及相关流程概览 springboot是基于spring的新型的轻量级框架,最厉害的地方当属自动配置。那我们就可以根据启动流程和相关原理来看看,如何实现传奇的自动配置 二、springboot的启动类入口 用过springboot的技术人员很显而易见的两者之间的差别就是视觉上很直观的:springboot有自己独立的启动类(独立...

javarrr的博客 5万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

SpringBoot启动流程解析(总结的非常好,很清晰!)

由于该系统是底层系统,以微服务形式对外暴露dubbo服务,所以本流程中SpringBoot不基于jetty或者tomcat等容器启动方式发布服务,而是以执行程序方式启动来发布(参考下图keepRunning方法)。 本文以调试一个实际的SpringBoot启动程序为例,参考流程中主要类类图,来分析其启动逻辑和自动化配置原理。 总览: 上图为Sprin...

咖啡的博客 3万+

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

SpringBoot启动流程及其原理

SPRINGBOOT启动流程及其原理 Spring Boot、Spring MVC 和 Spring 有什么区别? 一 springboot启动原理及相关流程概览 二 springboot的启动类入口 三 单单是SpringBootApplication接口用到了这些注解   1)@Configuration注解   2)@ComponentScan注解 3)@EnableAutoConfiguration AutoConfigurationPackage注解: ...

zzk00007的博客 4727

一文搞懂SpringBoot启动流程及自动配置

SpringBoot启动流程。## 标题 1、启动SpringBoot启动类SpringbootdemoApplication中的main方法。 2、调用SpringApplication.run(SpringbootdemoApplication.class, args),该方法是一个静态方法。 public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) { return

qq_44530691的博客 1万+

[springboot]springboot启动流程

Spring Boot程序有一个入口,就是main方法。main里面调用SpringApplication.run()启动整个Spring Boot程序,该方法所在类需要使用@SpringBootApplication复合注解。 其中需要关注的是: @SpringBootApplication注解其实是包含了三个注解: @EnableAutoConfiguration:SpringBoot根据应用所声明的依赖来对Spring框架进行自动配置。简单概括一下就是,是借助@Import的帮助,将所有符合自动配

浅夜 9251

springboot启动流程和Tomcat启动

springboot启动流程和Tomcat启动springboot启动函数新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 springboot启动函数 @SpringBootApplication(scanBasePack

weixin_43955575的博客 2949

SpringBoot的启动流程

相信每一个Java开发者对于SpringBoot都不会陌生,SpringBoot的出现,极大的简化了我们开发web应用的难度。此外,SpringBoot简化配置提供了默认配置,减少了开发人员需要进行手动配置的工作,从而提高了开发效率。快速开发提供了许多开箱即用的功能和模板,使开发人员能够快速构建应用程序,减少了样板代码的编写。内嵌式服务器支持内嵌式服务器(如等),无需额外配置,可以轻松部署应用程序。自动化配置提供了自动配置机制,可以根据项目的依赖自动配置应用程序,减少了手动配置的繁琐工作。

qq_62086292的博客 1091
上一篇: SpringBoot: 可执行jar的特殊逻辑
下一篇: Java核心: 类加载器
randy.lou
博客等级 码龄15年 853粉丝 77原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值