Spring 启动详解

2023-11-02

Springboot启动流程

方法入口: org.springframework.boot.SpringApplication#run(java.lang.String…)

  1. StopWatch 开启,公开总运行时间和每个命名任务的运行时间
  2. getRunListeners(args) : 获取SpringApplicationRunListener 监听者
  3. prepareEnvironment(): 准备环境,并发送环境准备事件给相关listeners,这时候有ConfigFileApplicationListener时可以从配置文件读取environment,可通过EnvironmentPostProcessor处理环境参数
  4. configureIgnoreBeanInfo() : spring.beaninfo.ignore配置
  5. printBanner: 打印banner
  6. createApplicationContext(): 根据应用类型新建 ConfigurableApplicationContext 容器
  7. prepareContext: 设置环境变量,初始化容器,加入BeanDefinitionLoader用于后面载入BeanDefinition,然后载入一些系统和main方法主类的beanBeanDefinition
  8. refreshContext: 刷新容器
  9. afterRefresh , stopWatch.stop() 结束刷新上下文

listener相关事件: starting,environmentPrepared,contextPrepared, contextLoaded, started, running, failed, callFailedListener
在正在开启,启动完成,失败,环境准备,容器准备,容器载入完成时会通过容器事件回调。

  • 注意点: 如果使用spring cloud那么会在环境准备environmentPrepared时,有BootstrapApplicationListener会监听该事件,并启动父容器,父容器名称默认为"bootstrap"

读取配置文件问题与详解

问题:springboot 父容器无法读取 spring子容器的配置文件中的参数值?

入口: org.springframework.boot.context.config.ConfigFileApplicationListener#postProcessEnvironment

  1. 通过参数spring.profiles.active/include 属性中初始化配置文件信息,可以通过环境变量来配置需要读取的文件,做不同开发环境的处理
  2. load 加载文件,相关代码
private void load(Profile profile, DocumentFilterFactory filterFactory,
				DocumentConsumer consumer) {
	//  getSearchLocations()是通过spring.config.location获取配置文件的路径去加载文件
	getSearchLocations().forEach((location) -> {
		boolean isFolder = location.endsWith("/");
		// getSearchNames()是通过 spring.config.name获取配置文件的名称,默认为application
		Set<String> names = (isFolder ? getSearchNames() : NO_SEARCH_NAMES);
		names.forEach(
				(name) -> load(location, name, profile, filterFactory, consumer));
	});
}
  1. 父容器相关配置
    入口: org.springframework.cloud.bootstrap.BootstrapApplicationListener#bootstrapServiceContext
    相关代码:
String configName = environment.resolvePlaceholders("${spring.cloud.bootstrap.name:bootstrap}");
String configLocation = environment.resolvePlaceholders("${spring.cloud.bootstrap.location:}");
Map<String, Object> bootstrapMap = new HashMap<>();
bootstrapMap.put("spring.config.name", configName);
if (StringUtils.hasText(configLocation)) {
	bootstrapMap.put("spring.config.location", configLocation);
}

答案:父容器默认读取配置文件 bootstrap.yml,也可以通过 ${spring.cloud.bootstrap.location:} 来添加修改读取配置文件的路径,可以解释为什么父容器无法读取spring中application.yml中的属性

ApplicationContext 容器refresh刷新详解

方法入口:org.springframework.context.support.AbstractApplicationContext#refresh

  1. 获取锁
  2. prepareRefresh(): 准备刷新,校验环境,此处可以重写 initPropertySources对环境校验
  3. obtainFreshBeanFactory(): 获取容器中的beanFactory,不存在就创建并初始化 BeanFactory, 存在则设置id
  4. prepareBeanFactory(): 填充BeanFactory 一些属性,解析器,回调接口等等
  5. postProcessBeanFactory(): 允许上下文子类容器子类对beanFactory做后置处理
  6. invokeBeanFactoryPostProcessors: 激活各种BeanFactory处理器,对所有的 BeanDefinitionRegistryPostProcessors 、手动注册的 BeanFactoryPostProcessor 以及通过配置文件方式的 BeanFactoryPostProcessor 按照 PriorityOrdered 、 Ordered、no ordered 三种方式分开处理、调用, 这里委托给PostProcessorRegistrationDelegate实现,其中BeanDefinitionRegistryPostProcessor此处解析了一些注入的类Configuration,Import注解
  7. registerBeanPostProcessors: 注册 BeanPostProcessor,排序加入beanFactory
  8. initMessageSource: 初始化上下文中的资源文件,如国际化文件的处理等
  9. initApplicationEventMulticaster: 初始化上下文事件广播器
  10. onRefresh: 给上下文子类可扩展初始化其他特殊Bean, spring mvc中的bean是在此处定义,tomcat用线程池创建bean
  11. registerListeners: 在所有bean中查找listener bean,然后注册到广播器中
  12. finishBeanFactoryInitialization: 初始化剩下的单例Bean(非延迟加载的)
  13. finishRefresh: 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
  14. destroyBeans: 销毁beans
  15. cancelRefresh: 重置容器激活标签
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring 启动详解 的相关文章

  • MCP

    文献名 Identification of candidate plasma protein biomarkers for cervical cancer using the multiplex proximity extension as
  • 华为OD机试 - 高矮个子排队(Java)

    题目描述 现在有一队小朋友 他们高矮不同 我们以正整数数组表示这一队小朋友的身高 如数组 5 3 1 2 3 我们现在希望小朋友排队 以 高 矮 高 矮 顺序排列 每一个 高 位置的小朋友要比相邻的位置高或者相等 每一个 矮 位置的小朋友要
  • BUCK电路

    一 Buck电路原理图 Buck电路 又称降压电路 其基本特征是DC DC转换电路 输出电压低于输入电压 输入电流为脉动的 输出电流为连续的 二 Buck电路工作原理 当开关管Q1驱动为高电平时 开关管导通 储能电感L1被充磁 流经电感的电
  • oracle默认用户名、密码

    一般来说 安装ORACLE时 若没有为下列用户重设密码 则其默认密码如下 用户名 密码 登录身份 说明 sys change on install SYSDBA 或 SYSOPER 不能以 NORMAL 登录 可作为默认的系统管理员 sys
  • pytorch迁移学习载入部分权重

    载入权重是迁移学习的重要部分 这个权重的来源可以是官方发布的预训练权重 也可以是你自己训练的权重并载入模型进行继续学习 使用官方预训练权重 这样的权重包含的信息量大且全面 可以适配一些小数据的任务 即小数据在使用迁移学习后仍然能够保持良好的
  • IE被www.537.com,www.COXDX.INFO劫持,修复~

    一位同事的电脑中IE一直使用265网址导航作首页 这天忽然变成hxxp www COXDX INFO z012了 修改不回来 请我帮忙检修 打开Internet选项 手动修改首页为http www 265 com 但总不能生效 将该电脑中的
  • Qt5学习笔记:Qt两个窗口(Widget)间传递数据

    0x01 原理介绍 Qt两个窗口之间传递数据实际上还是利用了信号与槽的概念来实现 本质上讲 我们只需要实现A窗口发射信号 B窗口槽函数响应信号即可 首先我们在A窗口的头文件中定义发射的信号 signals void sendSignal Q
  • 如何进行网站性能优化?

    分享人 chenxingxing 目录 1 背景介绍 2 知识剖析 3 常见问题 4 解决方案 5 编码实战 6 扩展思考 7 参考文献 8 更多讨论 一 背景介绍 前端优化的目的 1 用户 体验好 2 服务商 节省资源 简而言之 就是在不
  • mq的概念

    1 延迟队列 概念 延迟队列存储的是对应的延迟消息 所谓 延迟消息 是指当消息被发送以后 并不想让消费者立刻拿到消息 而是等待特定时间后 消费者才能拿到这个消息进行消费 应用场景 当你在网上购物的时候是否会遇到这样的提示 十分钟之内未付款
  • SDC时序约束 - create_clock

    在写 sdc约束文件时 要做的第一件事情就是使用create clock对进入FPGA的时钟进行约束 其语法格式如下 create clock add name
  • Ranger配置HDFS报错:curl: (3) [globbing] nested braces not supported at pos 2

    Ambari上显示错误信息 2017 11 06 13 01 00 618 Will retry 65 time s caught exception u Execution of curl location trusted k negot
  • 【Matlab】提取excel中的数据画折线图

    1 前言 在日常数据分析时 将数据保存为xlsx的格式进行存储 本文利用xlsread函数对excel数据进行提取 并利用其数据进行二维图像的绘制 2 excel中数据内容 3 代码 1代表sheet1 pwd xlsread C User
  • 第二周-目录命名规则及用途,文件的元数据,软连接和硬连接

    1 描述Linux发行版的系统目录名称命名规则以及用途 命名规则 文件和目录被组织成一个单根倒置树结构 文件系统从根目录下开始 用 表示 文件名称区分大小写 文件系统分层结构 LSB Linux Standard Base 标准Linux文
  • 初识vue3

    对vue3的理解 2020年9月发布的正式版 vue3支持大多数的Vue2的特性 Vue中设计了一套强大的组合APi代替了Vue2中的option API 复用性更强了 更好的支持TS 最主要 Vue3中使用了Proxy配合Reflect代
  • notepad++中配置python IDE

    操作系统是windows7 notepad 版本是5 9 6 2的安装版 python版本是2 7 2 windows7下的python安装配置在http blog csdn net gabriel1026 article details
  • 《算法和数据结构》数学基础总结

    前言 算法是什么 数学是什么 算法中的数学又是什么 这篇文章 让我来为大家介绍下法中的数学基础 数学可以说是算法的基石 所谓万丈高楼平地起 如若根基不稳 那么再高的楼 也只是豆腐渣工程 随时都有塌陷的可能 所以数学之于算法 可谓 非常重要
  • vmware 虚拟机开机自启动脚本

    1 建立一个txt文件 D VMware VMware Workstation vmrun exe T ws start I Documents Virtual Machines centos centos vmx nogui 注意 如果路
  • Python学习之爬取网页图片(单张)

    import requests import os os 库是Python标准库 包含几百个函数 常用的有路径操作 进程管理 环境参数等 root D pictures url input 请输入图片链接 让用户输入图片链接 path ro
  • 【JVM】JVM内存模型(详细)

    目录 一 JVM概述 1 jvm简介 2 jvm作用 3 jvm的内存模型 二 类加载器 1 类加载器的作用 2 加载器的类型 3 双亲委派机制的运行过程 4 双亲委派机制优缺点 5 为什么要破坏双亲委派机制 6 破坏双亲委派机制的方式 三
  • 函数调用堆栈的过程

    函数在进行调用时会产生开栈和清栈的操作 那么就来介绍一下函数调用堆栈的过程吧 首先 利用一个小例子来研究这个过程 include

随机推荐

  • Android禁止view上下滑动,Android RecyclerView禁止滑动

    在开发时 数组返回数目很少 需求要求不能左右滑动 下面是一种解决方案 1 RecyclerView 为垂直状态 VERTICAL 下 LinearLayoutManager layoutManager new LinearLayoutMan
  • 1929:【04NOIP普及组】火星人

    题干 这道题有好多废话 不过和全排列非常像 全排列题目 所以这道题数字的大小顺序与全排列的默认顺序一模一样 全排列的代码 在这里 本题就是一次次地调用全排列 不愿意麻烦的 就是我 可以用STL 非常方便 代码 100分 include
  • Stream:findFirst()高效简洁遍历集合中的一个元素

    业务开发中会运用到很多的List
  • sonarqube项目按权限分配

    一 创建用户 进入sornarqube的配置中心 选择权限菜单下的用户菜单 然后点击Create User按钮 只要输入登录名 用户名与密码保存后就可以创建一个新用户 二 创建组 选择权限下的群组菜单进入用户组管理页面 点击Create G
  • 时序数据交叉验证方法与python实现

    文章目录 传统N折交叉验证方法 时序数据交叉验证方法 方法1 窗口拆分 方法2 带间隔的窗口拆分 方法3 拓展窗口切分 时序交叉验证python复现 传统N折交叉验证方法 传统的N折交叉验证示意图如下图所示 时序数据交叉验证方法 由于时间序
  • 谨慎对待Go语言中对interface的nil判断

    谨慎对待Go语言中对interface的nil判断 在进行Go语言编程中 我们会看见诸如if err nil 或者if err nil 之类的判断 这跟go语言的错误处理哲学 计划失败而非成功 及早失败 有关 大多数情况下 我们对一个err
  • StringRedisTemplate运行NullPointerException的完全解决

    SpringBoot在使用Redis时出现StringRedisTemplate运行NullPointerException的完全解决 RedisTemplate运行NullPointerException的完全解决 三种解决方法 第一种
  • STM之SD卡

    SD卡基本函数 SPI InitTypeDef结构体 SPI 初始化结构体 1 SD Lowlevel Init 该函数初始化SPI相关外围时钟 配置GPIO引脚 调用SPI Init 初始化SPI InitStructre结构体 gt S
  • Linux下如何安装Anaconda、修改环境变量以及管理环境

    Linux下AI环境的搭建 Anaconda篇 1 第一步 安装anaconda 2 第二步 更改 调整系统环境PATH 3 第三步 创建适当的虚拟 python pip 工作区 3 第四步 如何使用conda来管理不同环境 1 第一步 安
  • java获取客户端操作系统_根据User-Agent,获得客户端浏览器和操作系统的信息

    碰到取客户端浏览器和操作系统信息的问题 网上找了很久 大多都是在页面中嵌入JS实现的 无法满足我的要求 所以 就自己写了个方法 可以在servlet中取到 我是根据每个浏览器User Agent的特征 来判断的 在windows xp中已测
  • 汇编实现排序——希尔排序

    希尔排序是把记录按下标的一定增量分组 对每组使用直接插入排序算法排序 随着增量逐渐减少 每组包含的关键词越来越多 当增量减至1时 整个文件恰被分成一组 算法便终止 以下是汇编实现的代码 S0 SEGMENT STACK DW 20 DUP
  • RabbitMQ学习(四)——高级特性

    RabbitMQ高级特性 1 1 消息的可靠投递 1 1 1 消息发送端 在使用RabbitMQ的时候 作为消息发送方式希望杜绝任何消息丢失或者投递失败的场景 RabbitMQ为我们提供了两种方式用来控制消息的投递可靠性模式 confirm
  • IDEA断点调试技巧,多张动图包教包会。

    文章目录 一 怎么开启断点调试 二 调试界面咋那么多按钮 1 返回断点位置 2 步过 3 步入 4 5 强制步入 步出 6 回退断点 7 断点跳到光标处 8 表达式计算 9 恢复程序 10 停止程序 11 查看所有断点 12 禁用断点 13
  • vs2017community进行DirectX开发_问题小节

    一 下载并安装vs及DirectX 1 vs版本 vs2017community 免费的 百度就有 2 我下载的DirectX版本 DXSDK Jun10 链接https pan baidu com s 1w7np5N E6QYqJXIr0
  • 微信小程序年月日时分选择器的实现

  • 基于VGG深度学习神经网络的猫狗数据集分类

    摘要 VGG网络是由牛津大学视觉几何组完成的基于深度卷积神经网络的大规模图像识别架构 该网络参考了AlexNet ZFNet OverFeat等经典的网络架构 从而得出的 这个架构参加了ILSVRC 2014比赛 取得了定位冠军 分类亚军的
  • 苹果App Store程序提交审核指南中文版

    注 lt 苹果应用商店审核指南 gt 中文翻译最近一次更新为2013 03 04 文中红色部分是相对于2013 03 04版本的新增内容 绿色部分代表更改的内容 蓝色表示苹果相关官方文档的链接 前言 感谢您付出宝贵的才华与时间来开发iOS应
  • cannot import name ‘__new_empty_tensor‘ 升级版本后依旧出现问题

    问题描述 原因说明 这是因为包版本过低导致的 升级到torchvision 0 9 0就没有这个问题了 后续问题 我发现更新了版本依旧出现 后面发现因为我是多版本Python 运行的时候使用了默认环境 更新包在另一个环境 所有出现了问题 解
  • 含源码,用Python实现浪漫烟花

    目录 前言 环境准备 代码编写 效果展示 前言 Python实现浪漫的烟花特效 现在很多地方都不能放烟花了 既然看不到 那作为程序猿的我们还不能自己用代码做一个吗 今天就带大家用代码做一个烟花特效吧 环境准备 这里使用到的库有 pygame
  • Spring 启动详解

    Springboot启动流程 方法入口 org springframework boot SpringApplication run java lang String StopWatch 开启 公开总运行时间和每个命名任务的运行时间 get