玩转 Spring Boot 原理篇(启动机制源码剖析)

Spring boot启动原理及相关组件 ConfigurationClassPostProcessor的优先级为最高,它会对项目中的@Configuration注解修饰的类(@Component、@ComponentScan、@Import、@ImportResource修饰的类也会被处理)进行解析,解析完成之后把这些bean注册到BeanFactory中。在github里,我把Spring Boot应用启动的拓展组件(自定义的应用初始器、监听器、事件、ApplicationRunner)都写了例子,可参照阅读。 阅读详情

0. 

bbec7897837f187cc0be68fef819a286.png

0.0. 历史文章整理

玩转 Spring Boot 入门篇

玩转 Spring Boot 集成篇(MySQL、Druid、HikariCP)

玩转 Spring Boot 集成篇(MyBatis、JPA、事务支持)

玩转 Spring Boot 集成篇(Redis)

玩转 Spring Boot 集成篇(Actuator、Spring Boot Admin)

玩转 Spring Boot 集成篇(RabbitMQ)

玩转 Spring Boot 集成篇(@Scheduled、静态、动态定时任务)

玩转 Spring Boot 集成篇(任务动态管理代码篇)

玩转 Spring Boot 集成篇(定时任务框架Quartz)

玩转 Spring Boot 原理篇(源码环境搭建)

玩转 Spring Boot 原理篇(核心注解知多少)

玩转 Spring Boot 原理篇(自动装配前凑之自定义Starter)

玩转 Spring Boot 原理篇(自动装配源码剖析)

0.1. Spring Boot 启动流程简图

d390155c9e0f6314047024d6eea566fb.png

通过读 Spring Boot 启动流程的源码,大体勾勒了上面一个简易的流程图,通过此图能够看出 Spring Boot 的启动生命周期以及事件贯穿其中,所以搞定了生命周期以及事件,那么Spring Boot 启动流程也就理解个八九不离十了。

在正式开始读 Spring Boot 启动流程源码之前,先大体了解 Spring Boot 生命周期以及相应的事件。

02bad684eeeab4ed17c95d5dbe31b2b4.png

  • starting: 开始启动中

  • environmentPrepared:环境已备好

  • contextPrepared:准备应用上下文、实例化

  • contextLoaded:上下文准备好

  • started:应用启动成功

  • ready:应用已准备好,可以处理接收请求

  • failed:启动过程遇到异常,启动失败

SpringApplicationRunListeners 类定义了 Spring Boot 启动时的生命周期,而在每个生命周期节点会广播相应的事件。

7f2ad298dbf086a756333bba38385bb3.png

其内部广播事件实际上是 SpringApplicationRunListener 接口对应的实现类支持,而该接口只有一个实现类 EventPublishingRunListener。

1. Spring Boot 源码剖析

万物之始,大道至简。

当应用开始执行时,会调用 SpringApplication.run 方法开始 Spring Boot 启动之旅。

a2ca782786a367f8d3f49de485207039.png

在 SpringApplication.run 方法内部,接着会调用 SpringApplication 重载的 run 方法,最终会调用 SpringApplication 的构造方法创建事例,并调用 run(args) 方法来完成真正的启动操作。

286ac19583c3dc633d87e726e1e64910.png

为了清晰撸码,最初级的读源码方式,便是尝试在源代码上加点注释,采用控制台打印关键步骤的方式剖析源码。

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
   System.out.println("【Spring Boot 源码剖析】-【SpringApplication 构造方法】- 进入");
   this.resourceLoader = resourceLoader;
   System.out.println("初始化资源加载器 resourceLoader,默认为值为:" + resourceLoader);


   System.out.println("判断主要加载资源类 primarySources:" + primarySources + " 是否为空,若为空则抛出 IllegalArgumentException 异常");
   Assert.notNull(primarySources, "PrimarySources must not be null");


   System.out.println("初始化主要加载资源类合并去重");
   System.out.println("\t 实现方式:通过数组转换成 List,然后构造成LinkedHashSet,完成去重操作");
   this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
   System.out.println("初始化主要加载资源类合并去重后结果为:" + primarySources);


   System.out.println("推断当前 WEB 应用类型,定义共有三种:SERVLET(servlet web 项目)、REACTIVE(响应式 web 项目)、NONE(非 web 项目)");
   this.webApplicationType = WebApplicationType.deduceFromClasspath();
   System.out.println("当前 WEB 应用类型为:" + webApplicationType);


   System.out.println("初始化引导程序注册的初始化器");
   System.out.println("\t 从 META-INF/spring.factories 读取 BootstrapRegistryInitializer 类的实例名称集合并去重");
   this.bootstrapRegistryInitializers = new ArrayList<>(
         getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
   System.out.println("\t 引导程序注册的初始化器初始化后的值为:" + this.bootstrapRegistryInitializers);


   System.out.println("设置应用上下文初始化器");
   System.out.println("\t 从 META-INF/spring.factories 读取 ApplicationContextInitializer 类的实例名称集合并去重、排序");
   setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
   System.out.println("\t 应用上下文初始化器的初始化后的值为:" + this.initializers);


   System.out.println("设置监听器");
   System.out.println("\t 从 META-INF/spring.factories 读取 ApplicationListener 类的实例名称集合并去重、排序");
   setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
   System.out.println("\t 监听器列表初始化后的值为:" + this.listeners);


   System.out.println("初始化主入口应用类");
   System.out.println("\t 通过当前调用栈,获取 main 方法所在类,并赋值给 mainApplicationClass");
   this.mainApplicationClass = deduceMainApplicationClass();
   System.out.println("\t 程序入口应用类为:" + this.mainApplicationClass);


   System.out.println("【Spring Boot 源码剖析】-【SpringApplication 构造方法】- 执行完毕");
}

通过控制台日志输出,可以把 SpringApplication 构造方法完成的功能简单概括如下。

bcaa2c5b4c5c3c96a466953fad8fa9f2.png

纵然 SpringApplication 构造方法里面实现再复杂,也不会脱离构造方法的功能,就是完成一系列参数的初始化操作罢了。

在 SpringApplication 构造方法调用完毕后,接着会调用 SpringApplication 对象的 run 方法,坊间也称之为 Spring Boot 启动时的运行方法,若想探究 Spring Boot 的启动流程,此方法不容错过。

public ConfigurableApplicationContext run(String... args) {
   //1、记录运行开始时间
   long startTime = System.nanoTime();
   //2、创建引导程序注册的上下文
   DefaultBootstrapContext bootstrapContext = createBootstrapContext();
   //3、初始化应用上下文
   ConfigurableApplicationContext context = null;
   //4、设置系统属性“java.awt.headless”的值,默认为true,用于运行headless服务器,进行简单的图像处理,
   //   多用于在缺少显示屏、键盘或者鼠标时的系统配置,很多监控工具如 jconsole 需要将该值设置为 true
   configureHeadlessProperty();
   //5、创建所有spring运行监听器并发布应用启动事件,简单说的话就是获取SpringApplicationRunListener类型的实例(EventPublishingRunListener对象),
   //  并封装进SpringApplicationRunListeners对象,然后返回这个SpringApplicationRunListeners对象。
   //  说的再简单点,getRunListeners就是准备好了运行时监听器EventPublishingRunListener
   SpringApplicationRunListeners listeners = getRunListeners(args);
   // 发布 SprintBoot 启动事件:ApplicationStartingEvent
   listeners.starting(bootstrapContext, this.mainApplicationClass);
   try {
      //6、初始化默认应用参数类
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
      //7、根据运行监听器、引导启动上下文和应用参数来准备 Spring 环境
      //  创建和配置environment,发布事件:ApplicationEnvironmentPreparedEvent
      ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
      configureIgnoreBeanInfo(environment);
      //8、打印 banner 信息
      Banner printedBanner = printBanner(environment);
      //9、创建应用上下文,可以理解为创建一个容器
      context = createApplicationContext();
      context.setApplicationStartup(this.applicationStartup);
      //10、准备应用上下文,该步骤包含一个非常关键的操作,将启动类注入容器,为后续开启自动化提供基础
      // 发布事件:ApplicationContextInitializedEvent,打印启动日志,打印 profile 信息,
      // 发布 ApplicationContext 加载完毕事件:ApplicationPreparedEvent
      prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
      //11、刷新应用上下文,内部完成 Spring IOC 容器创建过程,并且会进行自动装配的操作
      //   发布事件:ContextRefreshedEvent,标志着 ApplicationContext 初始化完成
      refreshContext(context);
      //12、应用上下文刷新后置处理,做一些扩展功能
      afterRefresh(context, applicationArguments);
      //13、计算启动耗时
      Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
      //14、输出日志记录执行主类名、时间信息
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
      }
      //15、发布程序已启动事件:ApplicationStartedEvent
      listeners.started(context, timeTakenToStartup);
      //16、调用 ApplicationRunner 和 CommandLineRunner
      callRunners(context, applicationArguments);
   } catch (Throwable ex) {
      handleRunFailure(context, ex, listeners);
      throw new IllegalStateException(ex);
   }
   try {
      Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
      //17、发布应用上下文就绪事件:ApplicationReadyEvent,标志着可以处理接收的请求了
      listeners.ready(context, timeTakenToReady);
   } catch (Throwable ex) {
      handleRunFailure(context, ex, null);
      throw new IllegalStateException(ex);
   }
   //18、返回应用上下文
   return context;
}

Spring Boot 启动步骤确实比较多,挑几行代码解说一二。

1.1. createBootstrapContext()

afcf8f424f239475b5f0e485723314a9.png

方法内部会创建 DefaultBootstrapContext 的一个实例,然后对 bootstrapRegistryInitializers (构造方法中从 META-INF/spring.factories 读取 BootstrapRegistryInitializer 类的实例名称集合并完成初始化操作)进行逐个初始化操作(个人理解:可以做应用启动前的初始化检查动作,例如从远端拿证书文件,获取密钥,服务启动时的口令等等)。

1.2. starting()

d055d0b07c5b862c63234d8e3ae6f004.png

从 spring.factories 读取 SpringApplicationRunListener 类实例名称,只有 EventPublishingRunListener 一个配置,所以调用 SpringApplicationRunListener 的方法,本质上调用的是 EventPublishingRunListener 这个实现类的方法。

928dae89771116874f2cda08f4aad989.png

接着创建 spring 运行监听器 SpringApplicationRunListeners 的实例,然后调用 starting 方法。

SpringApplicationRunListeners listeners = getRunListeners(args);
// 发布 SprintBoot 启动事件:ApplicationStartingEvent
listeners.starting(bootstrapContext, this.mainApplicationClass);

starting 方法内部会调用 doWithListeners 方法进行遍历监听器列表,触发发布启动事件。

e6e850c1dd0ec8f731ef3d12510e7404.png

ac9ba30ad25edf6e6c307aee693d906a.png

发布启动事件,最终由 EventPublishingRunListener 来负责完成。

d42c0b8aa66a630c1b24aa77b314e846.png

至此,会调用 multicastEvent 来完成 ApplicationStartingEvent 启动事件的发布。

1.3. prepareEnvironment()

d2cf13d3563e6d0b84cb3309eacb56c6.png

根据运行监听器、注册引导上下文和应用参数来准备环境。

b47c951207cf517191b578b5a257f7c3.png

接着调用 environmentPrepared 来广播 ApplicationEnvironmentPreparedEvent 事件。

5a5b025c59dc12501184fdc29223fd5f.png

最后交由 EventPublishingRunListener 来发布  ApplicationEnvironmentPreparedEvent 事件。

70e2e50103210c9ef09120f26454f34c.png

至此,会调用 multicastEvent 来完成  ApplicationEnvironmentPreparedEvent  环境准备工作已完成的事件发布。

1.4. printBanner() 方法

当环境就绪后,接着便是创建 Banner 及打印。

4aa8dd6cd96efa56dbd0ac3c166d9bf3.png

Banner 的形式,SpringBootBanner 为默认控制台输出,ResourceBanner 加载资源文件,例如banner.txt,ImageBanner 为图片资源 banner。

f8ad43e5621ae43d73faae21dab754f0.png

在 printBanner 方法内部,会创建 SpringApplicationBannerPrinter 实例,然后调用 print 方法完成 banner 打印。

d86b976bb63b877e466fd6c08850a7a7.png

1.5. createApplicationContext()

17d55d78bc53172217e450925771ea1d.png

创建应用上下文(容器),方法内部会依据应用类型创建不同的上下文容器。

885995eb17abf771b40cafa8012a58f5.png

1.6. prepareContext()

准备应用上下文,方法内部会调用 applyInitializers(context) 方法,此方法会对所有的 ApplicationContextInitializer 进行初始化操作。

f000fe30dcd7b747925183db9d465c25.png

接着会调用 listeners.contextPrepared(context) 触发 ApplicationContextInitializedEvent 上下文已实例化事件,接着会调用 getAllSources 方法加载所有资源,并将 Bean 加载到上下文中,然后广播 ApplicationPreparedEvent 上下文已准备好事件。

73e233dd417d1b5e53432493a80c1739.png

1.7. refreshContext(context)

96a3a3abc8d2c297a32ea216492531a7.png

刷新应用上下文,内部完成 Spring IOC 容器创建过程,并且会进行自动装配的操作以及发布ContextRefreshedEvent 事件,标志着 ApplicationContext 初始化完成。

1.8. afterRefresh()

f4fabc50ec21d8ef95c574f86859c98e.png

此方法是应用上下文刷新后置的处理,可以做一下功能扩展。

1.9.0. listeners.started()

98e4cd57bc9df2c84f9b9413c53b72d6.png

接着会计算启动耗时,并输出包含类名、启动耗时等信息的启动日志,然后发布 ApplicationStartedEvent 应用启动成功事件。

1.9.1. listeners.ready()

f528fffec9bed1f07d5907771e8ea53d.png

接着会调用 listeners.ready()   方法,并发布 ApplicationReadyEvent 应用已准备好事件,标志着应用可以处理接收的请求了。

1.9.2. handleRunFailure()

如果启动执行过程中出现异常,则会调用 listener.failed() 发布 ApplicationFailedEvent 事件。

c3fd74f414d40e78cc200b8816d4ce3e.png

至此,Spring Boot 应用就启动成功了,启动流程也就完事儿了,其实搞懂了 Spring Boot 的生命周期以及广播的事件,启动流程大体也就清晰了。

2. 例行回顾

本文采取 Debug 的方式跟了一下 Spring Boot 启动流程的源码,旨在感受一下启动机制的设计,这种设计在开发轮子时或许能够借鉴一下呢?

为了方便记忆,结合 Spring Boot 启动生命周期以及事件广播机制,把 Spring Boot 启动流程浓缩成了一副简图便于记忆。

6173121c193fdff60775845982bfb8e3.png

另外 Spring Boot 内嵌 Tomcat 是如何实现的呢?优雅停机是如何实现的呢?感兴趣可以自行先跟一下源码,下次将继续一起走进源码进行剖析。

一起聊技术、谈业务、喷架构,少走弯路,不踩大坑,会持续输出更多精彩分享,欢迎关注,敬请期待!

90c551f1c6ed25a352268b3ab10934ab.jpeg

参考资料:

https://spring.io/

https://start.spring.io/

https://spring.io/projects/spring-boot

https://github.com/spring-projects/spring-boot

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/

https://stackoverflow.com/questions/tagged/spring-boot

《Spring Boot实战》《深入浅出Spring Boot 2.x》

《一步一步学Spring Boot:微服务项目实战(第二版)》

《Spring Boot揭秘:快速构建微服务体系》

深入剖析 Spring Boot 中 @EnableAutoConfiguration:从源码到实际应用 从注解定义可以看出,注解使用了@Import注解导入了类,这是自动配置的关键类。是 Spring Boot 自动配置机制的核心所在,它通过触发类加载自动配置类,实现了根据项目依赖自动配置 Spring 应用的强大功能。从架构层面来看,自动配置机制借助约定和条件注解,有效减少了开发者的手动配置工作量,大幅提高了开发效率。从源码角度分析,我们能够深入理解自动配置类的加载过程和条件过滤机制。 阅读详情

相关推荐

spring boot源码解析(一)spring boot启动类SpringApplication

题外话 因工作原因,陆续开始接触spring boot,且对其源码和机制越来越发的需要深入了解。所以想系统的分析下spring boot源码,希望可以检查下去。 spring boot启动 @SpringBootApplication public class SimpleApplication { public static void main(String[] args) { Spri...

默默草 1255

Spring Boot 启动过程与自动配置详解:从源码到实现

分析SpringBoot启动配置原理:给出整体初步分析和对应流程图,并从三方面进行展开分析(SpringApplication构造过程分析+SpringApplication启动过程分析+SpringBoot自动配置分析)

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 6万+

Frida实战:如何用HashMap.put拦截法快速定位安卓App加密参数(附完整脚本)

本文详细介绍了如何使用Frida拦截HashMap.put方法快速定位安卓App加密参数,提供完整脚本和实战案例。通过动态分析技术,相比传统静态分析大幅提升效率,适用于电商、社交、金融等场景的加密参数定位。

jump7的博客 261

SpringBoot启动流程机制

对于Java语言中最流行的项目脚手架SpringBoot,相信很多程序员都和之前的我一样停留在会用却说不出它的启动流程的阶段,每次去好一点的甲方公司面试一旦面试官问到SpringBoot的详细启动流程是什么时都会很懵圈,大部分没有研究过SpringBoot框架源码的的小伙伴99%是答不上来的,然后面试官一句回去等消息吧直接凉凉。那么本文就带领还没有研究过SpringBoot框架源码的小伙伴们来捋一捋SpringBoot应用的启动流程机制。

UID_UUID的博客 598

PHP实战:5分钟搞定SM4国密加密算法集成(附完整代码)

本文提供了一份可直接用于生产环境的PHP SM4国密加密算法集成实战指南。文章详细解析了SM4算法核心,对比了ECB与CBC工作模式,并给出了包含完整代码、密钥管理、数据填充及性能优化的解决方案,帮助开发者快速、安全地在PHP项目中集成国密加密算法。

2a4s6d8f0g的博客 341

OpenClaw + Ollama 本地大模型部署教程:彻底告别Token焦虑

OpenClaw + Ollama 本地大模型部署教程:彻底告别Token焦虑

leaning_java的博客 1228

SpringBoot的启动机制

Import(AutoConfigurationImportSelector.class)包含一个selectImports()方法,该方法包括getAutoConfigurationEntry()方法,该方法读取classpath下的META-INF/spring.factories文件的配置,将相应的bean的配置项读取出来,通过反射机制实例化为配置文件,然后注入spring容器。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类。

qq_46130027的博客 243

64.企业级案例(上)-金融行业DDD落地全流程支付系统-附架构演进图

本文以金融支付系统为例,完整展示了DDD在企业级项目中的落地流程。首先通过事件风暴识别核心业务领域,包括交易、渠道、账务等限界上下文。在战略设计中划分上下文边界,确定交易上下文为核心域。战术设计聚焦交易上下文,详细设计了支付单聚合、值对象和支付路由服务。架构实现采用CQRS+EDA模式,通过命令端处理交易,查询端异步更新读模型,并利用防腐层隔离外部渠道。案例展示了DDD从业务探索到架构实现的全过程,体现了其在复杂业务系统中的价值。

yonggeit的博客 3039

SpringBoot启动原理

第三个问题是传统的web容器比如jetty本质上是直接通过java start.jar 来启动,之后来加载spring上下文的,SpringBoot通过main函数是怎么来启动web容器。2> 传统的web容器比如jetty本质上是直接通过java start.jar 来启动,之后来加载spring上下文的,SpringBoot通过main函数是怎么来启动web容器的呢?即:带着问题去看,debug跟踪源码验证 的方法。文本用带有少许说明的三个问题开场展开论述,实际是使用了麦肯锡大法中的SCQA架构。

qq_38470315的博客 1049

深入解析基于Fluent的蒸发冷凝相变UDF程序及其在重力热管液体蒸发冷凝变化计算中的应用

ANSYS Fluent是一款功能强大的CFD软件,广泛应用于流体流动、传热、化学反应和多相流等领域的数值模拟。Fluent提供了丰富的物理模型和求解器,支持用户自定义函数(UDF)以扩展其功能,实现更为复杂和特定的模拟需求。UDF是用C语言编写的程序,允许用户在Fluent中自定义物理模型、边界条件、源项等,以实现特定的模拟需求。在处理复杂的相变过程、非均匀物性参数或特定的热传导机制时,UDF提供了极大的灵活性和扩展性。

qq_38334677的博客 1265

【CASS精品教程】013:CASS9.1生成标准图幅案例教程

在CASS中,可以很方便的生成标准图幅,如50*50。本文演示cass中,根据测区范围标准图幅生成过程。

智慧空间实验室 1万+

spring boot的启动过程及原理剖析

本文详细介绍了spring boot启动过程及原理,并结合源码进行了剖析。

weixin_52641852的博客 1387

Uniapp返回上一页并刷新:亲测有效的 goBack 实现技巧!

这个技巧在实际开发中非常常用,特别适合表单提交后返回列表刷新这类场景。比起依赖onShow或复杂的vuex状态同步,这种方式更直接、好维护,也不容易出 bug。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1843

玩转 Spring Boot 原理篇(源码环境搭建)

0.0.0. 历史文章整理玩转 Spring Boot 入门篇玩转 Spring Boot 集成篇(MySQL、Druid、HikariCP)玩转 Spring Boot 集成篇(MyBatis、JPA、事务支持)玩转 Spring Boot 集成篇(Redis)玩转 Spring Boot 集成篇(Actuator、Spring Boot Admin)玩转 Sprin...

一猿小讲 2380

OpenClaw Windows 安装指南

好的,我来一步一步带你在 Windows 上安装 OpenClaw。

m0_60605453的博客 550

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

玩转 Spring Boot 原理篇(内嵌Tomcat实现原理&优雅停机源码剖析)

0.0.0. 历史文章整理玩转 Spring Boot 入门篇玩转 Spring Boot 集成篇(MySQL、Druid、HikariCP)玩转 Spring Boot 集成篇(MyBatis、JPA、事务支持)玩转 Spring Boot 集成篇(Redis)玩转 Spring Boot 集成篇(Actuator、Spring Boot Admin)玩转 Sprin...

一猿小讲 661

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Spring Boot 机制三: ApplicationContext 生命周期与事件机制源码解析

Component@OverrideSystem.out.println("收到事件: " + event.getMessage());事件触发阶段用途SpringApplication.run() 开始日志/监控Environment 初始化完成自定义属性处理ApplicationContext 创建完成注册 Beanrefresh 前容器准备完成refresh 后Bean 已初始化应用完全启动启动后逻辑启动失败异常处理。

Java、Python、AI、前沿技术等领域的技术总结和经验分享。 5597

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Spring Boot 启动流程源码解析

本文解析了Spring Boot的启动流程,主要分为四个阶段: 启动前准备:初始化SpringApplication,加载初始器和监听器,打印Banner 创建应用上下文:实例化ApplicationContext并准备环境 刷新上下文:加载Bean定义,实例化单例Bean 启动完成:发布就绪事件 关键点包括: 通过run()方法启动,完成应用类型推断 从spring.factories加载初始器和监听器 使用StopWatch监控启动时间 事件驱动机制贯穿整个启动过程 启动流程通过分层设计实现了高度可扩展

qq_43414012的博客 1704

Spring Boot 启动流程的深度剖析

Spring Boot 是一个基于 Spring 框架的开源项目,旨在简化 Spring 应用的创建、配置和运行。Spring Boot 的启动流程可以概括为:加载配置 -> 创建上下文 -> 执行自动配置 -> 初始化各种组件 -> 启动应用。通过对 Spring Boot 启动流程的深入剖析,我们对 Spring Boot 的工作机制有了更清晰的认识。结合源码的解读,我们能够更好地理解各个环节的实现原理。希望本文能够帮助读者在实际开发中更好地运用 Spring Boot 框架。

持续分享有趣的技术干货 1198

四,分析Spring Boot底层机制(Tomcat 启动分析+Spring容器初始化+Tomcat如何关联 Spring 容器) 以及个人编写启动 Tomcat

在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。

weixin_61635597的博客 2906

深入源码:Spring Boot 内置 Tomcat 的实现机制分析

Spring Boot,Tomcat的组成,Connector,Container,AbstractApplicationContext,onRefresh(),AnnotationConfigServletWebServerApplicationContext,ServletWebServerApplicationContext,createWebServer,getWebServerFactory,getWebServer,WebServerStartStopLifecycle

qq_26733517的博客 1551

【Spring】Spring Boot启动过程源码解析

本文深入解析SpringBoot启动流程,从入口类分析到完整容器初始化过程。启动过程分为两大阶段:1) SpringApplication构造阶段,完成应用类型判断、初始化器和监听器加载;2) run方法执行阶段,包含9个关键步骤:环境准备、Banner打印、容器创建、前置处理、容器刷新、后置处理等。重点剖析了事件发布机制(如ApplicationStartingEvent)、配置加载优先级、自动配置原理等核心机制,并指出初始化器和监听器通过spring.factories加载的特殊性。

小七的博客 1314

深入剖析Spring Boot启动过程:从源码到实践

在当今Java生态系统中,Spring Boot已经成为企业级应用开发的事实标准。作为Spring Framework的扩展,它通过约定优于配置的理念,极大地简化了基于Spring的应用开发流程。理解Spring Boot的启动机制,不仅能够帮助开发者更好地驾驭这个框架,还能在遇到问题时快速定位和解决。

zuiyuelong的博客 1048

Spring boot启动源码之run方法

Spring boot启动源码之run方法 前言 我们知道,Spring boot其实功能上,和Spring是一样的,只不过Spring boot更加方便开发,所以Spring boot的启动源码,本质上是和Spring一样的,只不过相比较于Spring的启动关键方法refresh(),只是对refresh()进行了一些封装,以及一些前置处理,后置处理。 1、run方法的大致流程概述 2、run方法源码 public ConfigurableApplicationContext run(Strin.

yuanchangliang的博客 3086

02-Spring Boot启动原理核心源码剖析

Springboot启动原理

weixin_43761434的博客 892

Spring Boot类加载机制深度剖析

Spring Boot通过定制类加载机制实现了可执行Jar运行、自动配置等核心特性。其采用简化的两层类加载器模型,移除Tomcat的CommonClassLoader,由SpringBootClassLoader和嵌入式容器类加载器构成。可执行Jar通过LaunchedURLClassLoader加载BOOT-INF目录资源,突破标准Jar限制。自动配置通过类路径扫描spring.factories实现,DevTools热部署采用双类加载器架构(BaseClassLoader+RestartClassLoa

weixin_43114485的博客 1387
上一篇: 玩转 Spring Boot 原理篇(自动装配源码剖析)
下一篇: 玩转 Spring Boot 原理篇(内嵌Tomcat实现原理&优雅停机源码剖析)
一猿小讲
博客等级 码龄15年 294粉丝 156原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值