springboot 启动过程

https://blog.csdn.net/mnicsm/article/details/93893669  SpringBoot启动流程总结

https://zhuanlan.zhihu.com/p/457739559   SpringBoot启动流程总结很好

SpringBoot启动过程 版本是2.4.5

第一步new了一个SpringApplication对象 ,第二部调用了run()方法 ,底层还是用的spring应用,springboot 只是把一些我人工的配置,和功能场景,通过start包,提前装配好。

黄色标记的都是组件。我们可以实现组件,加入自己的逻辑。在启动过程中,springboot每完成一个重要的组件初始化,都要通知springboot 的监听器的。

1.准备阶段  (创建SpringApplication(springBoot应用)通过spring 的spi 机制反射获取初始化类和监听器

  1. 判定web容器类型  (通过是否引入了xxx.servet 包,还是引入了xx.reactive 包 来判断选择那容器)

       如果存在org.springframework.web.reactive.DispatcherHandler类并且org.springframework.web.servlet.DispatcherServlet类不存在的时候,则决定当前使用REACTIVE模式容器

    如果javax.servlet.Servlet类、org.springframework.web.context.ConfigurableWebApplicationContext类任意一个不存在,则决定当前使用NONE模式(即非web容器)

    否则采用SERVLET容器模式

    由于spring-boot-starter-web依赖引入了tomcat(包括了javaee规范)和spring-web,所以会自动选择SERVLET模式

  2. 找ApplicatinContextlnitializer;去spring.factories找 ApplicatinContextlnitializer 

    ●用于在spring容器刷新之前初始化初始化Spring应用的 ConfigurableApplicationContext的回调接口 ,通常用于需要对应用程序上下文进行编程初始化的web应用程序中。例如,根据上下文环境注册属性源或激活配置文件等。

    ●List<ApplicationContetInitializer<?> > initializers

  3. 找ApplicationListener ;应用监听器。去spring.factories找 ApplcationListener    是spring 应用的监听器,作用于整个Spring上下文,范围更广。

    ■List<ApplicationListener<?>> listeners

  4. 找到main 方法所在类。

    ● 比如获取主配置类并保存,获取到主配置类了,就可以回去类的注解,(@SpringBootApplication=》@EnableAutoConfiguration)后面就可以执行自动配置功能。

通过手动创建一个RuntimeException对象,获取到当前方法堆栈,并一直向上推,直到推到main方法所在类并返回

2.运行阶段 ( 主要是 获取springboot的监听器,通过 广播相应的事件(ApplicationEvent)给相应的spring 的监听器(ApplicationListener)处理,  创建ApplicationContext 对象(spring 应用),把以前获取到的配置赋值给ApplicationContext,最后执行spring的refresh方法 

  1 .StopWatch 记录应用的启动时间

  2.让当前应用进入headless模式。java.awt.headless

  3. 获取所有RunListener (springboot运行监听器) [为 了方便所有Listener进行事件感知]

    ●getspringFactoriesInstances 去spring.factories找SpringApplicationRunListener  

    ●遍历SpringApplicationRunListener调用starting方法:  并通过 EventPublishingRunListener(广播事件)通知准备阶段获取ApplcationListenerpring 应用的监听器。ApplicationListener的实现类会被SpringApplicationRunListener代理执行。

    ●相当于通知所有感兴趣的人,springboot应用正在启动。

  4保存命令行参数: ApplicationArguments

  5准备环境prepareEnvironment () ;

    ■返回或者创建基础环境信息对象。StandardServletEnvironment

    ■当前会创建AnnotationConfigServletWebServerApplicationContext

3. 创建ApplicationContext I0C createApplicationContext

4. 准备ApplicationContext I0C容器的基本信息prepareContext0

  ■保存环境信息

  ■I0C容器的后置处理流程.

  ■应用初始化器; applylnitializers;

    ●遍历所有的ApplicationContextinitializer. 调用initialize.. 来对ioc容器进行初始化扩展功能

    ●遍历所有的listener调用contextPrepared. EventPublishRunListenr; 通知所有的监听器contextPrepared

  ■所有的监听器调用contextLoaded.通知所有的监听器contextLoaded;

5. 刷新IOC容器。refreshContext

  ■创建容器中的所有组件(Bean 的生命周期逻辑 )

  。容器刷新完成后工作? afterRefresh

  。所有监听器调用listeners started(context;通知所有的监听器started)

6. afterRefreshApplicationContext 构造方案。容器准备好以后你想干点啥。

 

7. 调用所有runners; callRunners0    springBoot项目启动时候,有时候需要再启动之后直接执行某一段代码。这个时候就用到了 ApplicationRunner /CommandLineRunner 这个类。

  ■获取容器中的ApplicationRunner

  ■获取容器中的CommandLineRunner

  ■合并所有runner并且按照@Order进行排序

  ■遍历所有的runner.调用run方法

8.如果以上有异常

  ■调用Listener的failed

。调用所有监听器的running方法lsteners.unningicontext: 通知所有的监听器running

。running如果有问题。 继续通知filed。调用所有Listener的filed; 通知所有的监听器falled

posted @ 2023-05-29 16:23  好记性不如烂笔头=>  阅读(105)  评论(0编辑  收藏  举报