SpringBoot源码阅读3-启动原理

@SpringBootApplication
public class DistApplication {public static void main(String[] args) {// 启动入口SpringApplication.run()SpringApplication.run(DistApplication.class, args);}
}

1、服务构建

这里"服务"指的是SpringApplication对象,服务构建就是指创建SpringApplication对象。

创建对象肯定离不开构造器,SpringApplication类的构造器如下

// 一般都使用这个构造器
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {// 1.记录传入的资源加载器this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");// 2.记录主方法类(是一个set集合)this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));// 3.确定Web服务类型(reactive / servlet / node)// 确定方式也很简单就是判断当前工程是否存在一些特殊的类如 org.springframework.web.reactive.DispatcherHandler 就是reactive类型// 默认是 servletthis.webApplicationType = WebApplicationType.deduceFromClasspath();// 4.加载初始化类 - 读取当前工程所有META-INF/spring.factories 文件(这个文件配置了上下问题初始化配置类、监听器类等)// BootstrapRegistryInitializer 启动注册初始化器,SpringBoot本身没有默认的"注册初始化"器所以这里是加载不到注册初始化器除非是有自定义的this.bootstrapRegistryInitializers = new ArrayList<>(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));// ApplicationContextInitializer 上下文初始化器setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));// ApplicationListener 监听器setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 5.通过运行栈 stackTrace 判断出 main 方法所在的类(就是启动类本身)// 后面发布启动事件要用this.mainApplicationClass = deduceMainApplicationClass();// 至此 SpringApplication 对象就构造完成了
}

以监听器为例

在这里插入图片描述

然后就是调用run()进入环境准备阶段,详见以下代码

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {// 创建完 SpringApplication 对象后调用run()方法return new SpringApplication(primarySources).run(args);
}

2、环境准备

这个阶段主要就是为即将要诞生的"容器"做一些充足的准备。

public ConfigurableApplicationContext run(String... args) {if (this.registerShutdownHook) {SpringApplication.shutdownHook.enableShutdownHookAddition();}long startTime = System.nanoTime();// 1.创建 DefaultBootstrapContext 对象,并逐一调用initialize()启动注册初始化器的初始化方法(刚刚从 META-INF/spring.factories 文件加载到的 BootstrapRegistryInitializer)// 默认情况下这里只是创建了 DefaultBootstrapContext 对象,因为SpringBoot没有默认的注册初始化器DefaultBootstrapContext bootstrapContext = createBootstrapContext();ConfigurableApplicationContext context = null;// 2.设置系统环境变量 java.awt.headless=true 表示缺少显示器、键盘等输入设备也可以正常启动configureHeadlessProperty();// 3.启动"服务"本身的运行监听器SpringApplicationRunListeners listeners = getRunListeners(args);// 4.发布启动事件(事件监听者为前面我们从 META-INF/spring.factories 文件加载到的7个监听器)listeners.starting(bootstrapContext, this.mainApplicationClass);try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);Banner printedBanner = printBanner(environment);context = createApplicationContext();context.setApplicationStartup(this.applicationStartup);prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);refreshContext(context);afterRefresh(context, applicationArguments);Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);}listeners.started(context, timeTakenToStartup);callRunners(context, applicationArguments);}catch (Throwable ex) {throw handleRunFailure(context, ex, listeners);}try {if (context.isRunning()) {Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);listeners.ready(context, timeTakenToReady);}}catch (Throwable ex) {throw handleRunFailure(context, ex, null);}return context;
}

3、容器创建

4、填充容器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/40047.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年港澳台联考考生成绩数据分析来啦

分数线 出炉 2024年的港澳台联考正式出分&#xff01;根据考生成绩&#xff0c;全国联招划档线如下&#xff1a; 一、本科批次 &#xff08;一&#xff09;普通类院校&#xff08;专业&#xff09;&#xff1a;文史类365分、理工类390分&#xff08;部分院校执行高分线&#…

持续直击WCCI 2024:金耀初教授、台湾省台北分会等获殊荣 横滨夜景美不胜收

持续直击WCCI 2024&#xff1a;金耀初教授、台湾省台北分会等获殊荣&#xff01;横滨夜景美不胜收&#xff01; 会议之眼 快讯 会议介绍 IEEE WCCI&#xff08;World Congress on Computational Intelligence&#xff09;2024&#xff0c;即2024年IEEE世界计算智能大会&…

BAS(入侵与攻击模拟)正在替代红队测试?

之前经常会被用户问到&#xff0c;漏扫、渗透和红队红的区别是啥&#xff1f; 传统的漏扫、渗透和红蓝对抗&#xff0c;可以看到工具化的漏洞不可靠&#xff0c;人工的成本就高。怎么找到一个漏洞可信度又高&#xff0c;成本又低的&#xff0c;就诞生了BAS。 抛开漏扫&#xf…

umi项目中的一些趣事

前言 出于某些安全问题&#xff0c;需要把HTML中框架注入的umi版本信息去掉&#xff0c;那要怎么搞呢~ 方案 查找官方文档&#xff0c;没发现可以去掉注入信息的方法&#xff0c;但在一番折腾后&#x1f609;终究还是解决了~ 发现 版本信息是从这里注入的~ Object.define…

解决pip安装时的“SyntaxError: invalid syntax”错误

项目场景&#xff1a; 项目中有新的成员加入时&#xff0c;第一步就是安装开发环境&#xff0c;然而往往同样的机器、同样的配置&#xff0c;我们却总能遇到各种各样不同的问题。 今天分享一个简单的操作问题。 问题描述 项目用到pandas&#xff0c;安装pandas时遇到Syntax…

Java后端每日面试题(day2)

目录 Session和Cookie的关系Cookie与Session的区别JWT 由哪些部分组成&#xff1f;如何防止 JWT 被篡改&#xff1f;JWT 的特点 Session和Cookie的关系 Session和Cookie都可以用来实现跟踪用户状态&#xff0c;而二者是关系的&#xff1a;Session的实现依赖于Cookie。 Session…

【C语言】顺序表经典算法

本文介绍的是两道顺序表经典算法题目。 移除元素 &#xff08;来源&#xff1a;LeetCode&#xff09; 题目 分析 我们很容易想到的办法是去申请一个新的数组&#xff0c;遍历原数组不等于val就把它拿到新数组里。但是题目的要求是不使用额外空间&#xff0c;所以这种方法我们…

Python面向对象编程中的继承及其应用

目录 1. 继承的基本概念 2. 继承的语法 3. 继承的应用场景 4. 使用示例&#xff1a;汽车销售系统 5. 总结 继承是面向对象编程中的一个重要概念&#xff0c;它允许我们根据已有类创建新类&#xff0c;并继承已有类的属性和方法。在本文中&#xff0c;我们将学习Python中的…

Unity3D中,AI角色Rigidbody旋转导致的动画问题

在制作一些AI角色的时候&#xff0c;可能会运用到Rigidbody组件来使AI角色拥有一些相关的物理属性&#xff0c;但是AI角色在受到一些物理碰撞或者惯性等原因&#xff0c;会发生旋转导致动画出现意料外的错误&#xff0c;比如在由动转静的时候&#xff0c;可能会发生向前翻转等一…

卷积层里的填充和步幅

一、定义 1、对于卷积&#xff0c;我们另一个超参数是核的大小&#xff0c;通常使用的卷积核是33或者55&#xff0c;很少用偶数核 2、填充是为了让输出不变或者变大&#xff0c;是为了在输入不太大&#xff0c;又能使模型足够深的情况下使用 3、填充&#xff1a;在输入周围添…

【Java学习笔记】java图形界面编程

在前面的章节中&#xff0c;我们开发运行的应用程序都没有图形界面&#xff0c;但是很多应用软件&#xff0c;如Windows下的Office办公软件、扑克牌接龙游戏软件、企业进销存ERP系统等&#xff0c;都有很漂亮的图形界面。素以需要我们开发具有图形界面的软件。 Java图形界面编程…

Megatron-DeepSpeed与Megatron-LM在reduce grad上的差异

Megatron-DeepSpeed与Megatron-LM在reduce grad上的差异 一.Megatron-DeepSpeed 实现【deepspeed/runtime/engine.py】二.ModelLink 实现【ParamAndGradBuffer】1.ParamAndGradBuffer功能介绍2.实现原理A.分配一大块内存B.获取视图C.all_reduce grad 测试DP1,TP2,PP1,MBS1,zero…

【信即是功夫】人皆有良知在心中

良知就是做人、做事的准则&#xff0c;良知就是天理&#xff1b;实实在在地自信 每个人心中都有一个圣人&#xff0c;只因自己不能真的相信&#xff0c;把这个圣人埋没了 良知在每个人心中&#xff0c;无论你如何做&#xff0c;也无法泯灭它。即使身为盗贼的人&#xff0c;他…

WebStorm配置路径别名(jsconfig.json)

项目是 ViteVueTs 新建一个 jsconfig.json文件 {"compilerOptions": {"baseUrl": ".","paths": {"/*": ["./src/*"]}},"exclude": ["node_modules", "dist"] }然后在 vite.confi…

Sping源码(九)—— Bean的初始化(非懒加载)—mergeBeanDefinitionPostProcessor

序言 前几篇文章详细介绍了Spring中实例化Bean的各种方式&#xff0c;其中包括采用FactoryBean的方式创建对象、使用反射创建对象、自定义BeanFactoryPostProcessor以及构造器方式创建对象。 创建对象 这里再来简单回顾一下对象的创建&#xff0c;不知道大家有没有这样一个疑…

day01-切片和索引

day01-切片和索引 ndarray对象的内容可以通过索引或切片来访问和修改&#xff0c;与 Python 中list 的切片操作一样。 ndarray数组可以基于0-n的下标进行索引 注意&#xff0c;数组切片并不像列表切片会重新开辟一片空间&#xff0c;而是地址引用&#xff0c;需要使用.copy()…

算法day1 两数之和 两数相加 冒泡排序 快速排序

两数之和 最简单的思维方式肯定是去凑两个数&#xff0c;两个数的和是目标值就ok。这里两遍for循环解决。 两数相加 敲了一晚上哈哈&#xff0c;结果超过int范围捏&#xff0c;难受捏。 public class Test2 {public static void main(String[] args) { // ListNode l1 …

IO多路复用学习

Linux中的I/O多路复用 相关基础概念 在学习I/O多路复用之前&#xff0c;先学习一些相关的基础概念&#xff0c;便于理解。 内核缓冲区和用户缓冲区 &#x1f62e; CPU 上会运行两种程序&#xff0c;一种是操作系统的内核程序&#xff08;也称为系统程序&#xff09;&#x…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(二十)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 30 节&#xff09; P30《29.数据持久化-用户首选项》 实现数据持久化在harmonyOS中有很多种方式&#xff0c;比较常见的是以下两…

OpenCV教程02:图像处理系统1.0(翻转+形态学+滤波+缩放+旋转)

-------------OpenCV教程集合------------- Python教程99&#xff1a;一起来初识OpenCV&#xff08;一个跨平台的计算机视觉库&#xff09; OpenCV教程01&#xff1a;图像的操作&#xff08;读取显示保存属性获取和修改像素值&#xff09; OpenCV教程02&#xff1a;图像处理…