spring boot 启动流程详解

news/2024/11/2 17:35:33/

主启动类

@SpringBootApplication
@MapperScan("com.example.mapper")
public class StableBootApplication {public static void main(String[] args) {SpringApplication.run(StableBootApplication.class,args);}
}

SpringApplication类中有个静态run()方法,最终执行如下:

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {return (new SpringApplication(primarySources)).run(args);}

显然 分为两部分

  1. 实例化(new) SpringApplication。
  2. 执行run()方法。

阅读 SpringApplication类的构造函数
在这里插入图片描述

实例化 SpringApplication
获取并且设置应用类型(重要)

应用类型有三种:

  1. NONE:顾名思义,什么都没有,正常流程走,不额外的启动web容器,比如Tomcat。
  2. SERVLET:基于servlet的web程序,需要启动内嵌的servletweb容器,比如Tomcat。(常用)
  3. REACTIVE:基于reactive的web程序,需要启动内嵌reactiveweb容器,作者不是很了解,不便多说

源码如下:

static WebApplicationType deduceFromClasspath() {if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null) && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null) && !ClassUtils.isPresent("org.glassfish.jersey.servlet.ServletContainer", (ClassLoader)null)) {return REACTIVE;} else {String[] var0 = SERVLET_INDICATOR_CLASSES;int var1 = var0.length;for(int var2 = 0; var2 < var1; ++var2) {String className = var0[var2];if (!ClassUtils.isPresent(className, (ClassLoader)null)) {return NONE;}}return SERVLET;}
}
获取并且设置初始化器以及监听器

初始化器以及监听器 调用的方法都是 getSpringFactoriesInstances(类型Type)。
最终逻辑是 从 从类路径META-INF/spring.factories中 加载 初始化器以及监听器 。
初始化器(ApplicationContextInitializer): 初始化某些 IOC容器刷新之前的组件。
监听器(ApplicationListener): 监听特定的事件 比如IOC容器刷新、容器关闭等。

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {ClassLoader classLoader = this.getClassLoader();// 从 META-INF/spring.factories 中获取Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));// 根据名称实例化List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);AnnotationAwareOrderComparator.sort(instances);return instances;
}
小结

SpringApplication的构建都是为了run()方法启动做铺垫,最重要的部分就是设置应用类型、设置初始化器、设置监听器。

注意: 初始化器和这里的监听器都要放置在spring.factories文件中才能在这一步骤加载,否则不会生效。因为此时IOC容器还未创建,所以即使将其注入到IOC容器中也是不会生效的。

在这里插入图片描述

执行run() 方法

上面分析了SpringApplication的构建过程,一切都做好了铺垫,现在到了启动的过程了。

获取、启动运行过程监听器

监听器(SpringApplicationRunListeners): 监听应用程序启动过程。

获取 loadFactoryNames()方法从spring.factories文件中获取值:

org.springframework.boot.SpringApplicationRunListener=
org.springframework.boot.context.event.EventPublishingRunListener

启动运行监听器

//执行starting()方法
listeners.starting(bootstrapContext, this.mainApplicationClass);
环境构建

加载系统配置以及用户的自定义配置(application.properties)

ConfigurableEnvironment environment =
this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);    
创建IOC容器
context = this.createApplicationContext();

在这里插入图片描述

很显然 我这里是 SERVLET 故创建的是 AnnotationConfigServletWebServerApplicationContext()。

这一步仅仅是创建了IOC容器,未有其他操作

刷新IOC容器的前置处理(重要)
this.prepareContext(bootstrapContext, context, environment, listeners, 
applicationArguments, printedBanner);
调用初始化器

从spring.factories取值的

将自定义的ApplicationContextInitializer放在META-INF/spring.factories中,在此时也是会被调用。

加载启动类,注入容器
两次广播事件
listeners.contextPrepared(context);
load(context, sources.toArray(new Object[0]));
刷新IOC容器(重要)

刷新容器完全是Spring的功能了,比如初始化资源,初始化上下文广播器等
tomcat内置应用服务器在此时启动

刷新IOC容器的后置处理
this.afterRefresh(context, applicationArguments);

默认为空,如果有自定义需求可以重写,比如打印一些启动结束日志等。

发出结束执行的事件
执行Runners
小结

在这里插入图片描述

未完待续…

springboot启动流程详解(清晰易懂)

springboot内置服务器tomca启动详解

spring boot源码解读


http://www.ppmy.cn/news/1450539.html

相关文章

使用通义千问,为汽车软件需求生成测试用例

前几篇文章我们介绍了,分析需求,生成代码,生成流程图,序列图等汽车软件开发设计中的常见工作步骤,今天我们讲下汽车软件测试中怎么使用大模型,如何用千问生成用例,具体操作步骤如下: 提示词: 车速自动闭锁 使能条件(a&b&c&d&e&f) a. 电源状态…

小程序地理位置接口权限直接抄作业

小程序地理位置接口有什么功能&#xff1f; 随着小程序生态的发展&#xff0c;越来越多的小程序开发者会通过官方提供的自带接口来给用户提供便捷的服务。但是当涉及到地理位置接口时&#xff0c;却经常遇到申请驳回的问题&#xff0c;反复修改也无法通过&#xff0c;给的理由也…

微信公众号 点击显示答案 操作步骤

1、右键进入检查模式 2、ctrlf查找html元素 3、添加答案区域代码 添加答案区域代码后&#xff0c;可以直接在页面进行格式调整 <!-- 此处height控制显示区域高度 --> <section style"height: 500px;overflow-x: hidden;overflow-y: auto;text-align: center;bo…

JAVA基础之接口

目录 什么情况下使用接口&#xff1f; 什么是接口&#xff1f; 为什么要使用接口&#xff1f; 接口是一种规范 接口是一种能力 什么情况下使用接口&#xff1f; 只有抽象方法的抽象类可以用接口表示。 什么是接口&#xff1f; 为什么要使用接口&#xff1f; 接口是一种规…

AI视频教程下载:用ChatGPT做SEO的终极教程

ChatGPT是由OpenAI开发的一款尖端人工智能&#xff0c;它已经彻底改变了我们进行搜索引擎优化&#xff08;SEO&#xff09;的方式。其先进的语言处理能力使其成为增强网站内容、提高搜索引擎排名和显著提升在线可见性的宝贵工具。 这个全面的课程旨在为你提供使用ChatGPT进行SE…

事件处理模式--reactor原理与实现

文章目录 reactorapicode reactor reactor是是服务器的重要模型, 是一种事件驱动的反应堆模式 通过epoll_create() 创建句柄, epoll_ctrl()提前注册好不同的事件处理函数 , 当事件到来就由 epoll_wait () 获取同时到来的多个事件&#xff0c;并且根据数据的不同类型将事件分发…

unity制作app(3)--gps定位

1.unity中定位Unity之GPS定位&#xff08;高德解析&#xff09;_unity gps定位-CSDN博客 代码需要稍微修改一下&#xff0c;先把脚本绑到一个button上试一试&#xff01; 2.先去高德地图认证&#xff08;app定位&#xff09; 创建应用和 Key-Web服务 API | 高德地图API (ama…

预训练模型介绍

一、什么是GPT GPT 是由人工智能研究实验室 OpenAI 在2022年11月30日发布的全新聊天机器人模型, 一款人工智能技术驱动的自然语言处理工具 它能够通过学习和理解人类的语言来进行对话, 还能根据聊天的上下文进行互动,能完成撰写邮件、视频脚本、文案、翻译、代码等任务 二、 为…