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.rhkb.cn/news/367600.html

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

相关文章

【QT】概述|对象树模型|两种控件模式|信号和槽|lambda

目录 什么是QT 特点 QT程序 main函数 QT按钮 纯代码模式 图形化模式 对象树模型 信号和槽 连接与断开 自动连接 断开连接 信号的发射 lambda表达式 基本语法 捕获列表 Lambda表达式用于信号与槽的连接 例如 什么是QT Qt是一个跨平台的C图形用户界面应用…

WAF的新选择,雷池 SafeLine-安装动态防护使用指南

什么是 WAF WAF 是 Web Application Firewall 的缩写&#xff0c;也被称为 Web 应用防火墙。 区别于传统防火墙&#xff0c;WAF 工作在应用层&#xff0c;对基于 HTTP/HTTPS 协议的 Web 系统有着更好的防护效果&#xff0c;使其免于受到黑客的攻击&#xff1b; 通俗来讲&#…

【数据库】Oracle安装报错(win10安装oracle提示环境不满足最低要求)

目录 一、问题场景&#xff1a; 二、问题描述 三、原因分析&#xff1a; 四、解决方案&#xff1a; 一、问题场景&#xff1a; 安装Oracle数据库 二、问题描述 安装之前提示&#xff08; [INS-13001]环境不满足最低要求。 是否确实要继续? &#xff09; 如图所示&…

运维锅总浅析云原生DevOps工具

本文从Tekton与Kubevela、Jenkins、GitLab CI的区别与联系对常见的云原生DevOps工具进行对比分析&#xff0c;最后给出DevOps工具选型思路。希望对您有所帮助&#xff01; 一、DevOps简介 DevOps是一种结合了软件开发&#xff08;Development&#xff09;和IT运维&#xff08…

1、项目基础

1、系统架构图 2、项目业务组成 3、技术选型 3.1 前端 vue3 ts sass axios 3.2后端 spring-cloud系列 gateway openfeign spring-cloud-alibaba系列 nacos sentinel seata

开放式耳机怎么选?五大2024年口碑销量爆棚机型力荐!

在选购开放式耳机的时候&#xff0c;我们总会因为有太多的选择而陷入两难&#xff0c;又想要一个颜值比较高的&#xff0c;又想要同时兼顾性能还不错的&#xff0c;所以作为测评博主&#xff0c;今天我们就给大家带来自己的一些选购技巧和自己觉得还不错开放式耳机&#xff0c;…

TP8/6 子域名绑定应用

原www.xxx.com/admin改为admincms.xxx.com config/app.php

3d模型里地毯的材质怎么赋予?---模大狮模型网

在进行3D建模时&#xff0c;赋予地毯逼真的材质是营造现实感和增强场景氛围的重要步骤。模大狮将介绍在常见的3D建模软件中&#xff0c;如何有效地为地毯赋予各种材质&#xff0c;以及一些实用的技巧和注意事项。 一、选择合适的地毯材质 在3D建模中&#xff0c;地毯的材质选择…

uniapp实现可拖动悬浮按钮(最新版2024-7月)

此章主要介绍如何使用uniapp跨平台开发&#xff0c;实现悬浮按钮&#xff0c;移动端经常会有所这样的需求&#xff0c;那么功能如下&#xff1a; 1.圆圈悬浮球&#xff0c;上下左右靠边显示 2.可以界面任何拖动&#xff0c;不会超出界面 3.单击悬浮球的点击事件 效果&#xf…

C++ 和C#的差别

首先把眼睛瞪大&#xff0c;然后憋住一口气&#xff0c;读下去&#xff1a; 1、CPP 就是C plus plus的缩写&#xff0c;中国大陆的程序员圈子中通常被读做"C加加"&#xff0c;而西方的程序员通常读做"C plus plus"&#xff0c;它是一种使用非常广泛的计算…

【Linux】线程——线程的概念、线程的特点、线程的优点和缺点、线程和进程、线程函数的使用

文章目录 Linux线程1. 线程的概念1.1 什么是线程 2. 线程的特点2.1 线程的优点2.2 线程的缺点2.4 线程和进程 3. 线程函数的使用pthread_create() 创建线程pthread_self() 获取线程IDpthread_exit() 线程终止pthread_cancel() 线程取消pthread_join() 线程等待pthread_detach()…

Android跨进程通信,binder传输数据过大导致客户端APP,Crash,异常捕获,监听异常的数值临界值,提前Hook拦截。

文章目录 Android跨进程通信&#xff0c;binder传输数据过大导致Crash&#xff0c;异常捕获&#xff0c;监听异常的数值临界值&#xff0c;提前Hook拦截。1.binder在做跨进程传输时&#xff0c;最大可以携带多少数据1.1有时候这个1m的崩溃系统捕获不到异常&#xff0c; 2.监测异…

视频编解码从H.264到H.266:浅析GB28181安防视频汇聚EasyCVR视频压缩技术

随着信息技术的飞速发展&#xff0c;视频编解码技术也在不断革新&#xff0c;以适应高清、超高清甚至8K视频时代的到来。视频编解码技术作为数字多媒体领域的核心技术之一&#xff0c;也在不断地演进和革新。从早期的H.261到现在的H.265、H.266&#xff0c;每一次技术的升级都极…

二叉树的层序遍历/后序遍历(leetcode104二叉树的最大深度、111二叉树的最小深度)(华为OD悄悄话、数组二叉树)

104二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 本题可以使用前序&#xff08;中左右&#xff09;&#xff0c;也可以使用后序遍历&#xff08;左右中&#xff09;&#xff0c;…

线下生鲜蔬果店做小程序有什么方法

生鲜蔬果是生活所需&#xff0c;大小商家众多&#xff0c;零售批发各种经营模式&#xff0c;小摊贩或是超市门店都有着目标客户或准属性群体。竞争和获客转化也促进着商家寻找客源和加快线上进程。 尤其是以微信社交为主的私域场景&#xff0c;普客/会员都需要精细化管理营收和…

什么是带有 API 网关的代理?

带有 API 网关的代理服务显著提升了用户体验和性能。特别是对于那些使用需要频繁创建和轮换代理的工具的用户来说&#xff0c;使用 API 可以节省大量时间并提高效率。 了解 API API&#xff0c;即应用程序编程接口&#xff0c;是服务提供商和用户之间的连接网关。通过 API 连接…

Log4j日志框架讲解(全面,详细)

目录 Log4j概述 log4j的架构&#xff08;组成&#xff09; Loggers Appenders Layouts 快速入门 依赖 java代码 日志的级别 log4j.properties 自定义Logger 总结&#xff1a; Log4j概述 Log4j是Apache下的一款开源的日志框架&#xff0c;通过在项目中使用 Log4J&…

2024 年人工智能和数据科学的五个主要趋势

引言 2023年&#xff0c;人工智能和数据科学登上了新闻头条。生成性人工智能的兴起无疑是这一显著提升曝光度的驱动力。那么&#xff0c;在2024年&#xff0c;该领域将如何继续占据头条&#xff0c;并且这些趋势又将如何影响企业的发展呢&#xff1f; 在过去几个月&#xff0c;…

Sql审核平台Archery的搭建和简单配置

Sql审核平台Archery的搭建和简单配置 Archery是一个开源的Web应用&#xff0c;基于Python开发&#xff0c;利用Flask作为后端框架&#xff0c;前端采用Vue.js&#xff0c;构建了一个现代化的数据操作界面。提供了SQL审核、数据查询、报表生成等功能&#xff0c;同时支持多种数据…

qtreewidget 美化,htmlcss和qss 不是一个概念!已解决

这种样式的美化&#xff0c; 能气死个人&#xff0c;css 一个单词搞定&#xff0c;非要 在qss中。多少个单词不知道了。 m_tree_widget->setStyleSheet("QTreeView{background:transparent; selection-background-color:transparent;}""QTreeView::branch{b…