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

TC275-AutoSAR实战:Davinci Cfg多核OS配置与调试技巧

本文详细介绍了在TC275芯片上使用Davinci Cfg工具进行AutoSAR多核操作系统配置的实战步骤与调试技巧。内容涵盖从导入arxml文件的常见“坑”开始,到配置Det、EcuC、创建多核OS实例、关联OS应用、创建任务与设置优先级调度,最后分享了利用Det日志、调试器多核视图及处理核间通信与缓存一致性等关键调试方法,旨在帮助开发者高效完成复杂车载ECU软件集成。

weixin_29219189的博客 489

SpringBoot启动流程总结

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

mnicsm的博客 6万+

用deepseek部署全自动的机器人--bytebot

Bytebot是一款开源AI桌面代理,提供完整的虚拟桌面环境,支持跨应用任务处理、文件管理、文档处理等复杂工作流。其技术架构包含核心控制、LLM代理、UI等组件,支持Docker和Kubernetes部署。本文演示了基于CloudStudio的部署流程,包括环境配置、Docker部署及DeepSeek API集成,实现多模型调用功能。

Kin 2481

总结:Springboot启动流程

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

w2009211777的专栏 1万+

PMBus协议解析:基于I2C的电源管理实战与TMS320F28003x驱动开发

在嵌入式系统与服务器电源设计中,数字电源管理总线是实现高效、可靠电源监控与控制的关键技术。PMBus协议基于广泛应用的I2C总线物理层,通过定义标准化的命令集、数据格式与时序规范,为多路电源的电压电流监控、动态调整及故障处理提供了高效解决方案。其技术价值在于通过硬件自动处理协议解析、时钟拉伸与中断,显著降低软件复杂度,使开发者能聚焦于电源环路设计等核心逻辑。该协议广泛应用于服务器、通信基站及高性能计算板卡等场景,通过引入数据包错误检查、专用告警线等机制,确保了电源管理的可靠性。本文以TI TMS320F28

weixin_29189377的博客 374

天地图Api4.0.怎么根据geojson的数据。把一个省的所有市区标记色块和文字

天地图

肖肖肖丽珠的博客 1513

SPRINGBOOT启动流程及其原理

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

u014352080的专栏 3万+

告别交越失真:手把手教你设计高性能互补输出级电路(LTspice实测)

本文深入剖析音频放大器中常见的交越失真问题,并提供基于LTspice仿真的实战解决方案。通过对比二极管偏置、Vbe倍增器和集成运放驱动三种经典方案,手把手指导设计高性能互补输出级电路,涵盖原理分析、仿真验证及实物调试要点,助力消除音频失真,提升音质。

weixin_29190573的博客 552

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

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

qq_21609191的博客 1万+

SerDes硬件设计原理介绍

接收端:外部差分串行数据------线性均衡器----(CDR从数据中恢复出采样时钟)-----解串器(串行信号转并行信号)-------8B/10B的解码器或解扰器-----FIFO-----FPGA接受差分并行数据。发送端: FPGA发送差分并行数据----FIFO------8B/10B编码器或者扰码器-----串行器(并行信号转串行信号)-----均衡器(滤波)--------TX串行信号差分外发。串行器:8bit的并行数据----2bit的并行数据----1bits的串行数据。

weixin_42304393的博客 1109

掌控板玩板指南1:初识掌控板、扩展板、Mind+编辑器

掌控板、I/O扩展板入门

好乐无荒之地 1万+

SpringBoot 启动流程

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

qq_33807380的博客 9554

RV1126笔记二十七:MetaRTC6移植

MetaRTC6移植

6038

SpringBoot启动原理及相关流程

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

javarrr的博客 5万+

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

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

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

咖啡的博客 3万+

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

SpringBoot启动流程及其原理

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

zzk00007的博客 4727

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

一文搞懂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、付费专栏及课程。

余额充值