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,一经查实,立即删除!

相关文章

C++_02

1、类 1.1 什么是类 C 中的类&#xff08;class&#xff09;是一种编程结 构&#xff0c;用于创建对象。这些对象可以拥有属性&#xff08;即数据成员&#xff09;和行为&#xff08;即成员函数或方法&#xff09;。类的概念是面向对象编程的核心之一&#xff0c;其主要目的是…

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…

解析Kotlin中的Lambda【笔记摘要】

先看实例&#xff1a; fun b(param: Int): String {return param.toString() }fun a(funParam: (Int) -> String): String {return funParam(1) }a(::b) val d ::b1.双冒号 ::method 到底是什么&#xff1f;答&#xff1a;一个指向和该函数具有相同功能的对象的引用 因为…

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…

微信小程序tabar属性

微信小程序的TabBar是用于在小程序内创建底部导航栏的一种组件。它允许用户在多个页面之间快速切换&#xff0c;提高了用户体验。下面将详细讲解如何配置和使用微信小程序的TabBar。 配置TabBar {"pages": ["pages/index/index","pages/logs/logs&q…

计算机相关单词

以下是计算机学科中专业术语、软件、硬件、网络设备相关的一些术语&#xff1a; ps&#xff1a;涉及不懂的专有名词&#xff0c;需去主动了解&#xff0c;拓宽知识面 专业术语 API&#xff1a;Application Programming Interface&#xff0c;应用程序编程接口&#xff0c;允…

【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图形界面编程…

2024年上半年典型网络攻击事件汇总

文章目录 前言一、Ivanti VPN 的0 Day攻击(2024年1月)二、微软公司高管账户泄露攻击(2024年1月)三、Change Healthcare网络攻击(2024年2月)四、ConnectWise ScreenConnect漏洞利用攻击(2024年2月)五、XZ Utils软件供应链攻击(2024年3月)六、AT&T数据泄露攻击(20…

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…

使用Java实现实时地图应用

使用Java实现实时地图应用 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来探讨如何使用Java实现一个实时地图应用。 实时地图应用在现代互联网应用中…

Java_Spring框架:Bean的生命周期

在Spring框架中&#xff0c;Bean的生命周期包括以下几个阶段&#xff1a; 实例化&#xff08;Instantiation&#xff09;&#xff1a;在这个阶段&#xff0c;Spring会根据配置或注解创建Bean的实例。这可以通过构造函数实例化、工厂方法或者Bean容器中的其他方式来实现。 属性…

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

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