Spring Boot启动流程
加载启动类:加了@SpringBootApplication的启动类的main 方法中,通过运行SpringApplication.run()方法启动
【@SpringBootApplication是由@EnableAutoConfiguration(导入自动配置AutoConfigurationSelector类从而加载加了@Configuration的配置)、@SpringBootConfiguration(等同@Configuration)和@ComponentScan(自动扫描并加载符合条件的Bean)组成的 】
服务构建:构建SpringApplication
1.将资源加载器、主方法类记录在内存;
2.确定Web服务类型(Servlet-tomcat);
3.加载初始化类:读取META-INF文件中注册初始化、上下文初始化、监听器的配置;
4.通过运行栈(stackTrace)判断main方法所在的类(启动类本身);
进入run方法
环境准备:
1.new BootstrapContext(启动上下文)
2.调用启动注册初始化器中的初始化initialize方法(默认没有)
3.将java.awt.headless设置为true(表示缺少显示器键盘等输入设备也正常启动)
4.启动运行监听器(SpringApplicationRunListeners),然后发布启动事件(获取并加载spring-boot工程spring.factories配置文件中的EventPublishRunListener,引入监听器配置)
5.构建可配置环境Enviroment(默认Servlet类型):加载系统环境变量、jvm系统属性到propertySources的内存集合中,便于之后取用;通过配置环境configureEnvironment方法将启动时传入的环境参数args进行设置,同时在propertySources集合首个位置添加一个空配置configurationProperties(后续使用)
6.发送环境加载完成事件,刚加载的八个监听器会监听到,其中部分会进行相应处理,如环境配置后处理监听器会去加载spring.factories配置文件中的环境配置后处理器EnviromenPostProccessor(这里监听器用到了观察者模式,串行执行)
7..将spring.beninfo.ignore=true(Bean元数据信息不加载,属性、方法、构造函数)用来改善应用性能,打印Banner图(启动横幅)
容器创建:(ApplicationContext)
1.通过createApplicationContext来创建容器(上下文),首先根据服务类型(默认Servlet)创建容器ConfigurabaleApplicationContext,这个过程中会创建存放和生产bean实例的Bean工厂,创建用来解析@Component、@ComponentScan等注解的配置类后处理器ConfigurationClassPostProccessor,创建用来解析@Autowired、@Value等注解的自动注解Bean后处理器AutowiredAnnotationBeanPostProcessor
2.通过prepareContext方法对容器属性初始化,先用postProcessApplicationContext方法设置Bean名称生成器、资源加载器、类型转换器等,执行上下文初始化(实现容器ID、警告日志处理、日志监听等)ApplicationContextInitializer,为容器注册启动参数、Bean引用策略、Banner、懒加载策略等
3.通过Bean定义加载器将启动类等资源定义集合加载到BeanDefinitionMap(Bean定义池),便于后续根据Bean定义创建Bean对象
4.发布资源加载完成事件
填充容器:自动装配Bean
1.通过prepareRefresh方法,在已有的系统环境基础上准备servlet相关的环境Enviroment,通过初始化属性资源initServletPropertySources方法给servlet初始化参数servletContextInitParams和servletConfigInitParams赋值,然后通过validateRequiredProperties方法检验是否有必填的环境变量(可以在自定义初始化属性资源InitPropertySources方法中通过setRequiredProperties将某些环境变量设置为必填),最后完成监听器和事件初始化,环境准备完成
2.调用obtainFreshBeanFactory方法(如果选择ClassPathXmlApplicationContext作为容器,会重构BeanFactory和重新加载Bean定义,而选择的servletWebServerApplicationContext作为容器不会进行任何处理)
3.调用prepareBeanFactory方法加载类加载器BeanClassLoader、表达式解析器BeanExpressionResolver和配置文件处理器PropertyEditorRegistar等系统级处理器和两个Bean后置处理器(解析Aware接口的ApplicationContextAwareProcessor、处理自定义监听器注册和销毁的ApplicationListenerDetector),还会注册一些特殊Bean(BeanFactory容器本身、ApplicationContext、系统环境Enviroment、系统属性等)放入特殊对象池和单例池中
4.调用PostProcessBeanFactory方法对BeanFactory进行额外设置或修改(定义request、session等servlet相关作用域scopes,注册与servlet相关的ServletRequest、ServletResponse、HttpSession等特殊类)
5.执行InvokeBeanFactoryPostProcessors方法,执行BeanFactory后置处理器beanFactoryPostProcessor(其中包括配置处理器ConfigurationClassPostProcessor,该处理器加载所有@Configuration配置类,同时检索指定的Bean扫描路径componentScans,然后通过Bean扫描器ClassPathBeanDefinitionScanner中doScan方法扫描每个类,将所有扫描出来的Bean定义都放到Bean定义池beanDefinitionMap中,同样还会扫描加了@Bean、@Import等注解的类和方法,将他们对应的Bean定义也都放到Bean定义池,后续就能通过这些Bean定义构造相应的Bean对象了)
6.通过registerBeanPostProcessors方法检索所有的Bean后置处理器,同时根据指定的order为他们进行排序,然后放入后置处理器池beanPostProcessor中,每个Bean后置处理器都会在Bean初始化之前和之后分别执行对应的逻辑
7.通过initMessageSource方法和initApplicationEventMulticaster方法从单例池中获取两个Bean放在ApplicationContext中:messageSource(用于国际化,可以通过自定义messageSource这个Bean结合messages.properties配置文件进行多语言切换配置)、applicationEventMulticaster(用于自定义广播事件,可以通过publicshEvent方法进行事件发布)
8.通过onRefresh构造并启动Web服务器,先查找实现了ServletWebServerFactory这个接口的应用服务器Bean(默认为tomcat),通过getWebServer方法构造一个Tomcat对象,通过start方法进行启动,web服务器开始运行
9.通过registerListeners方法在Bean中查找所有的监听器Bean,将他们注册到上面的消息广播器applicationEventMulticaster中
10.通过finishBeanFactoryInitialization来生产我们所有的Bean(构造对象-填充属性-初始化实例-注册销毁,详情见springbean的生命周期),Bean生成后放入单例池singletonObjects中
11.通过finishRefresh方法构建并注册生命周期管理器lifecycleProcessor,同时会调用所有实现了声明周期接口Lifecycle的Bean中的start方法(当容器关闭时会自动调用对应的stop方法),发布一个容器刷新完成的事件,SpringBoot正式启动完成
相关文章:
Spring Boot启动流程
加载启动类:加了SpringBootApplication的启动类的main 方法中,通过运行SpringApplication.run()方法启动 【SpringBootApplication是由EnableAutoConfiguration(导入自动配置AutoConfigurationSelector类从而加载加了Configuration的配置&am…...
ARM day5
三盏灯流水 .text .global _start _start: 1.LDR R0,0X50000A28LDR R1,[R0]ORR R1,R1,#(0X1<<4)STR R1,[R0] 1.LDR R0,0X50000A28LDR R1,[R0]ORR R1,R1,#(0X1<<5)STR R1,[R0] 2.LDR R0,0X50006000LDR R1,[R0]BIC R1,R1,#(0X3<<20)ORR R1,R1,#(0X1<<…...
流程引擎概述及组成
流程引擎概述及组成 一、流程引擎概述 流程,可以理解为步骤,一个有序的活动或动作; 引擎,可以理解为驱动,是一个程序或者一套系统。 所以,字面意思可以理解为,流程引擎是一套(或…...
定时任务Apscheduler实践案例
定时任务Apscheduler实践案例 参考文章 https://blog.csdn.net/weixin_44799217/article/details/127353134 实现案例 本案例是使用定时任务apscheduler实现的每个三分钟发送一次邮件的任务 实现代码 import time from apscheduler.schedulers.blocking import BlockingSched…...
C#学习系列相关之多线程(五)----线程池ThreadPool用法
一、线程池的作用 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管…...
京东数据接口|电商运营中数据分析的重要性
在电商运营中,数据分析是非常重要的一环,它可以帮助电商企业更好地了解市场、了解消费者、了解产品、了解销售渠道等各种信息,从而制定更为科学有效的运营策略,提高销售效益。 数据方面用户可以直接选择使用数据接口来获取&#…...
C++入门(1)
目录 1.C关键字2.命名空间(namespace)2.1是什么2.2为什么2.3怎么用 3.C输入&输出4.缺省函数概念分类 5.函数重载6.引用6.1概念6.2特性6.3使用场景6.4引用和指针的不同点 1.C关键字 C总共有63个关键字 这里入门不多说,有需要的自行去了解 2.命名空间(namespac…...
redis-6.2.7 集群安装3主3从
因为资源有限准备了3 台 服务器,先查看防火墙的端口是否开放,如果没有开放先开放端口我使用的 6379 和 6380 这两个端口 所以将这两个端口放开。去redis 官网下载redis 安装包。下载地址 : redis 安装包下载 3. 安装redis 上传上去之后 3 台…...
【动态库】Ubuntu 添加动态库的搜索路径
在运行程序时,经常遇到下面这种动态库加载失败的情况,这时往往是系统在动态库的搜索路径下没有找到对应的库文件导致的。 目录 一、使用 LD_LIBRARY_PATH 二、修改 /etc/ld.so.conf 一、使用 LD_LIBRARY_PATH 环境变量 LD_LIBRARY_PATH是动态库的搜索…...
95740-26-4|用于体内DNA合成的探针F-ara-EdU
产品简介:(2S)-2-Deoxy-2-fluoro-5-ethynyluridine,一种用于体内DNA合成的探针,其毒性比EdU和BrdU都小。当需要延长细胞存活时间和不受干扰的细胞周期进展时,非常适合进行代谢DNA标记。 CAS号:95740-26-4 分子式&…...
Ajax使用流程
Ajax在不刷新页面的情况下,进行页面局部更新。 Ajax使用流程: 创建XmlHttpReqeust对象发送Ajax请求处理服务器响应 1. 创建XmlHttpReqeust对象 XmlHttpReqeust对象是Ajax的核心,使用该对象发起请求,接收响应 不同的浏览器创建…...
1808_ChibiOS基本的架构介绍
全部学习汇总: GreyZhang/g_ChibiOS: I found a new RTOS called ChibiOS and it seems interesting! (github.com) 简单看了一下ChibiOS的架构介绍,感觉这种OS以及组件非常适合快速构建一个应用。这里做一个简单的资料整理。。 1. 不同于其他的OS&#…...
曦力音视频转换工具Xilisoft Video Converter Ultimate mac中文版
Xilisoft Video Converter Ultimate mac是一款功能强大的视频转换软件,它可以将几乎所有流行的视频格式转换为其他格式,包括AVI、MPEG、WMV、DivX、MP4、H.264/AVC、AVCHD、MKV、RM、MOV、XviD、3GP等。此外,它还支持将视频转换为音频格式&am…...
Spring MVC 五:DispatcherServlet初始化之 mvc:annotation-driven
通过xml方式初始化DispatcherServlet时,xml文件中可以配置: <mvc:annotation-driven />或: <mvc:annotation-driven ><!--设置响应输出字符集--><mvc:message-converters><bean class"org.springframework.…...
uniapp EventChannel 页面跳转参数事件传递navigateBack,navigateTo 成功后通知事件区别
问题:navigateBack()emit事件在onload()监听不到 从A页面跳转到B页面,在B点击产生数据后,跳转回到A,并告诉A点击的数据是什么,使用: navigateBack()。 &…...
【C++ Primer Plus学习记录】指针——使用delete释放内存
当需要内存时,可以使用new来请求,使用完内存后,可以使用delete将其归还给内存池。 归还或释放(free)的内存可供程序的其他部分使用。 使用delete时,后面要加上指向内存块的指针(这些内存块最初…...
2023 NOIP A层联测9 - 风信子 题解
思路 我们可以考虑设 f l 0 , r 0 , l 1 , r 1 f_{l_0,r_0,l_1,r_1} fl0,r0,l1,r1 表示最大的 a l − a r a_l-a_r al−ar,其中 l ∈ [ l 0 , r 0 ] l\in [l_0,r_0] l∈[l0,r0], r ∈ [ l 1 , r 1 ] r\in [l_1, r_1] r∈[l1,r1…...
岩土工程安全监测无线振弦采集仪在无线组网的关键要点
岩土工程安全监测无线振弦采集仪在无线组网的关键要点 岩土工程是一种奇特而又极其重要的工程。它涉及到土地、岩石、气候等等因素,需要重视安全因素。而无线振弦采集仪作为一种常用的监测设备,可以采集岩土工程中的振动数据,从而确保工程的…...
代码随想录Day14 LeetCodeT110平衡二叉树 T257二叉树的所有路径 T404 左叶子之和
以下思路来自于: 代码随想录 (programmercarl.com) LeetCode T110 平衡二叉树 题目链接:110. 平衡二叉树 - 力扣(LeetCode) 题目思路 前面我们说过了,求二叉树的深度我们应该使用前序遍历,求二叉树的高度我们应该使用后序遍历,因为后序遍历可以将子树的…...
C语言自定义类型_枚举联合(3)
目录 枚举 什么是枚举类型? 枚举的声明 枚举的定义 枚举的优点 枚举的使用 联合(共用体) 什么是联合呢? 联合类型的定义 联合的特点 联合使用 联合大小的计算 联合的应用 今天接着我们来结束自定义类型。Ἑ…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
【若依】框架项目部署笔记
参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作: 压缩包下载:http://download.redis.io/releases 1. 上传压缩包,并进入压缩包所在目录,解压到目标…...
深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙
WebGL:在浏览器中解锁3D世界的魔法钥匙 引言:网页的边界正在消失 在数字化浪潮的推动下,网页早已不再是静态信息的展示窗口。如今,我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室,甚至沉浸式的V…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里
写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...
js 设置3秒后执行
如何在JavaScript中延迟3秒执行操作 在JavaScript中,要设置一个操作在指定延迟后(例如3秒)执行,可以使用 setTimeout 函数。setTimeout 是JavaScript的核心计时器方法,它接受两个参数: 要执行的函数&…...
结合PDE反应扩散方程与物理信息神经网络(PINN)进行稀疏数据预测的技术方案
以下是一个结合PDE反应扩散方程与物理信息神经网络(PINN)进行稀疏数据预测的技术方案,包含完整数学推导、PyTorch/TensorFlow双框架实现代码及对比实验分析。 基于PINN的反应扩散方程稀疏数据预测与大规模数据泛化能力研究 1. 问题定义与数学模型 1.1 反应扩散方程 考虑标…...
uni-app学习笔记三十--request网络请求传参
request用于发起网络请求。 OBJECT 参数说明 参数名类型必填默认值说明平台差异说明urlString是开发者服务器接口地址dataObject/String/ArrayBuffer否请求的参数App 3.3.7 以下不支持 ArrayBuffer 类型headerObject否设置请求的 header,header 中不能设置 Refere…...
