当前位置: 首页 > news >正文

spring boot启动源码分析(三)之Environment准备

上一篇《spring-boot启动源码分析(二)之SpringApplicationRunListener》

环境介绍:

spring boot版本:2.7.18

主要starter:spring-boot-starter-web

本篇开始讲启动过程中Environment环境准备,Environment是管理所有配置的实例对象,像application.yml、系统属性、环境变量等配置都可以通过Environment.getProperty(key)获取

入口如下:

(一)创建ConfigurableEnvironment

首先会从spring.factories中获取ApplicationContextFactory.class接口实现类,根据webApplicationType会实例化对应的ConfigurableEnvironment(这里是SERVLET,所以是AnnotationConfigServletWebServerApplicationContext.Factory创建的ApplicationServletEnvironment)

ApplicationServletEnvironment的类结构如下:

ApplicationServletEnvironment调用构造方法实例化时,父类AbstractEnvironment构造方法中会有初始化操作:

propertySources是Environment的核心属性,包含了各个配置源,这里赋值了一个MutablePropertySources,它实际是一个迭代器:

propertyResolver:是属性解析器,如占位符的解析等

AbstractEnvironment构造器采用类似模板方法将customizePropertySources(propertySources)交给子类实现,子类可以在此方法中加载数据源

可以看到子类StandardServletEnvironment,添加了StubPropertySource,桩配置源,类似打桩,这两个桩配置源分别是servletConfigInitParams和servletContextInitParams。这两个在webserver启动后会被替换成实际的配置源,这里只是个站位,没有实际的作用。

之后再次调用超类的customizePropertySources:

在StandardEnvironment中会添加两个重要的配置源,systemProperties和systemEnvironment。

systemProperties对应System.getProperties(),即所有的系统属性:

systemEnvironment对应的是System.getenv(),即系统的所有环境变量

(二)对Environment进行其他配置

     

        (1)首先添加conversionService:environment中的propertyResolver(配置解析器)配置应用转换服务,例如NumberToNumberConverterFactory,StringToCharacterConverter等。应该是为propertyResource中的数据解析时进行数据转换用的

        (2)configurePropertySources:

        如果SpringApplication中Map<String, Object> defaultProperties不为空,则会创建一个名为“defaultProperties”,实例类型为DefaultPropertiesPropertySource的配置源。

        java进程传入的命令行参数加载进配置源中,配置源名称为commandLineArgs,实例类型为CommandLinePropertySource。此方法为模板方法,可被子类覆盖实现自己的资源加载方式configureProfiles

        (3)此为空实现,看注释是说配置此应用程序环境中哪些配置文件处于活动状态(或默认情况下处于活动状态)。在配置文件处理过程中,可以通过{@code-spring.profiles.active}属性激活其他配置文件。

(三)绑定ConfigurationPropertySources

ConfigurationPropertySources.attach(environment);

增加一个名为“configurationProperties”的ConfigurationPropertySourcesPropertySource和environment绑定,实际上是把environment中所有的propertySource(也包括configurationProperties)包装进一个SpringConfigurationPropertySources实例中,而SpringConfigurationPropertySources是ConfigurationPropertySourcesPropertySource中的一个属性值,这也意味着configurationProperties可以访问所有的propertySource,这样它可以作为配置的统一访问入口。可以看如下configurationProperties对应实例属性

所以ConfigurationPropertySourcesPropertySource.getProperty(String name),实际上就是遍历每个PropertySource,获取它们的配置,但它对每个PropertySource进行了适配,以便以统一的接口进行获取配置。

getSource获取的是SpringConfigurationPropertySources,是一个迭代器,iterator()中会对配置源进行适配,适配成ConfigurationPropertySource

(四)发布environmentPrepared事件

事件的发布流程都差不多,这里不再赘述。主要差别是哪些监听器会监听了此事件,并做了什么逻辑处理。这里我们重点说一下这个:

主要有6个监听器:

代理监听器可以跳过,没有实际的逻辑处理。我们关注spring boot自定义的监听器。

(1)EnvironmentPostProcessorApplicationListener

这里主要是从spring.fatories获取EnvironmentPostProcessor接口实现类并实例化:

然后调用对应postProcessEnvironment,这些EnvironmentPostProcessor主要是添加不同的数据源配置,如ConfigDataEnvironmentPostProcessor解析我们常用的application.yml作为配置源,详情可看《Spring boot源码之EnvironmentPostProcessor》

(2)AnsiOutputApplicationListener

这里主要是根据spring.output.ansi.enabled和spring.output.ansi.console-available,设置AnsiOutput对应的属性。为输出到控制台的日志信息添加 ANSI 转义码,以实现彩色输出。这个用的比较少,我看只在打印banner和logback日志的颜色转换器中用到了

(3)LoggingApplicationListener

在上一篇发布starting事件中,日志系统进行了初步初始化,在这里则会完成全部的初始化。

a、getLoggingSystemProperties(environment).apply():会将配置文件中配置的日志相关配置设置到系统属性中,以便后续日志系统初始化时可以从系统属性读取。

如:配置文件中如果设置了logging.pattern.console,那么就会设置到系统属性变量CONSOLE_LOG_PATTERN中。这里还设置了PID以及下面的日志策略

b、initializeEarlyLoggingLevel(environment):初始化早期日志级别,实际只是根据Environment中是否配置debug和trace,设置springBootLogging对应级别

c、initializeSystem(environment, this.loggingSystem, this.logFile):这里是主要的初始化逻辑,如果之前日志已经初始化过,这里会使用spring boot会重新初始化,对日志进行增强。比如在logback中,会使用SpringBootJoranConfigurator,对配置文件进行加载解析,同时新定义了一些解析规则

所以在spring boot中可以使用springProperty,添加属性,值可以是Environment中配置的属性值

如上,是配置了一个pid变量,值是Environment中pid属性对应的属性值

d、initializeFinalLoggingLevels(environment, this.loggingSystem):初始化日志的最终的日志级别:

如果b步骤设置了springBootLogging,那么spring boot会初始化一些logger,设置其日志级别,如过是debug级别,则下图圈出来的都会设置是debug级别

另外则是对配置属性中有logging.level为前缀的设置其对应的日志级别:

如上,则会设置com.example为true。

e、registerShutdownHookIfNecessary(environment, this.loggingSystem)

往SpringApplication注册日志系统的shutdownHandler,会在shutdown发生时,停止日志上下文。

(4)BackgroundPreinitializer

启动一个后台线程去出发早期的初始化,并且有个countDownLatch,只有初始化完成,当ApplicationReadyEvent监听触发时,得等线程执行完才会继续执行,否则等待

(5)FileEncodingApplicationListener

        当系统设置了spring.mandatory-file-encoding编码格式时,会判断是否和System.getProperty("file.encoding")相同,如果不相等则抛出异常阻止系统的启动,默认没设置不影响

(五)其他

上面基本已经把环境变量准备完毕,剩下的是一些细微处理:

(1)将defaultProperties配置源移到最后,即查询资源时最后才查它

(2)SpringApplication相关环境变量绑定

即将spring.main开头的配置,绑定到对应SpringApplication的属性中。如spring.main.allow-circular-references=true,那么就会设置SpringApplication的allowCircularReferences值为true.

(3)Environment转换ConfigurableEnvironment为应用类型的环境,这里是ApplicationServletEnvironment,是ConfigurableEnvironment的子类,不需要转换

相关文章:

spring boot启动源码分析(三)之Environment准备

上一篇《spring-boot启动源码分析&#xff08;二&#xff09;之SpringApplicationRunListener》 环境介绍&#xff1a; spring boot版本&#xff1a;2.7.18 主要starter:spring-boot-starter-web 本篇开始讲启动过程中Environment环境准备&#xff0c;Environment是管理所有…...

MySQL复习

基础篇 InnoDB、MyISAM 和 MEMORY 存储引擎的区别&#xff1f; 主要区别&#xff1a; 为什么MySQL选择 InnoDB 作为默认存储引擎&#xff1f; 1.innodb支持事务&#xff0c;myisam、memory不支持。 2.innodb支持行级锁&#xff0c;可以使多个事务同时访问不同的行&#xf…...

ASP.NET Core 实现微服务 -- Polly 服务降级熔断

在我们实施微服务之后&#xff0c;服务间的调用变的异常频繁。多个服务之间可能是互相依赖的关系。某个服务出现故障或者是服务间的网络出现故障都会造成服务调用的失败&#xff0c;进而影响到某个业务服务处理失败。某一个服务调用失败轻则造成当前相关业务无法处理&#xff1…...

服务器漏洞修复解决方案

漏洞1、远程桌面授权服务启用检测【原理扫描】 Windows Remote Desktop Licensing Service is running: Get Server version: 0x60000604 1、解决方案&#xff1a;建议禁用相关服务避免目标被利用 方法一&#xff1a;使用服务管理器 打开“运行”对话框&#xff08;WinR&am…...

“AI智慧组卷系统:让考试变得更简单、更公平!

大家好&#xff0c;我是一名资深的产品经理&#xff0c;今天咱们就来聊聊教育领域的一款黑科技产品——AI智慧组卷系统。在这个信息技术飞速发展的时代&#xff0c;AI技术已经渗透到了我们生活的方方面面&#xff0c;教育行业也不例外。下面我就用大白话给大家介绍一下这个AI智…...

MT6706BL 同步整流 规格书

MT6706BL 是用于反激式变换器的高性能 65V 同步整流器。MT6706BL兼容各种反激转换器类型。MT6706BL 支持 DCM、CCM 和准谐振模式。MT6706BL 集 成 了 一 个 65V 功 率MOSFET&#xff0c;可以取代肖特基二极管&#xff0c;提高效率。V SW <V TH-ON 时&#xff0c;MT6706BL 内…...

vue el-table 数据变化后,高度渲染问题

场景&#xff1a;el-table设置了height属性&#xff0c;但是切换查询条件后再次点击查询重新获取data时&#xff0c;el-table渲染的高度会有问题&#xff0c;滚动区域变矮了。 解决办法&#xff1a;使用doLayout方法‌&#xff0c;在表格数据渲染后调用doLayout方法可以重新布局…...

前端多语言

前端多语言目前常用i18n实现 一、react 1.安装依赖 npm install react-i18next i18next --save2.创建配置文件 src/i18n config.ts&#xff1a;对 i18n 进行初始化操作及插件配置 en.json&#xff1a;英文语言配置文件 zh.json&#xff1a;中文语言配置文件 config.ts im…...

人工智能-机器学习之多元线性回归(项目实践一)

目标&#xff1a;运用scikit-learn进行多元线性回归方程的构建&#xff0c;通过实际案例的训练集和测试集进行预测&#xff0c;最终通过预测结果和MSE来评估预测的精度。 一、首先安装scikit-learn&#xff1a;pip install scikit-learn C:\Users\CMCC\PycharmProjects\AiPro…...

后台定时查杀进程策略

2019年做的一个500元价位内手机后台定时查杀的功能策略&#xff0c;现在2025年了回过头看&#xff0c;确实已经不适用了。现在进程管控大部分是不杀进程的方式了&#xff0c;类似冻结(类似苹果的墓碑机制)&#xff0c;而杀进程策略主要是场景式异常查杀了&#xff0c;例如明显性…...

Objective-C语言的学习路线

Objective-C语言的学习路线 在程序开发的历史长河中&#xff0c;Objective-C作为一种继承自C语言与Smalltalk的编程语言&#xff0c;扮演着重要的角色。虽然随着Swift语言的出现&#xff0c;Objective-C的使用有所减少&#xff0c;但它依然是iOS和macOS应用开发的重要基础&…...

宁德时代2025年Verify入职测评语言理解及数字推理真题SHL题库汇总、考情分析

宁德时代社招Verify入职测评对薪酬有着重要影响&#xff0c;其规定正确率达到80%才能顺利通过测评。这体现了公司对人才专业素养与能力的严格要求&#xff0c;旨在筛选出真正符合岗位需求的优秀人才。测评内容涵盖了专业知识、技能运用、逻辑思维等多方面&#xff0c;只有综合能…...

【Spring】注入方式

介绍 在Spring框架中&#xff0c;依赖注入&#xff08;Dependency Injection, DI&#xff09;是实现控制反转&#xff08;Inversion of Control, IoC&#xff09;的核心机制。 除了通过XML配置的注入方式&#xff08;已逐渐被淘汰&#xff09;&#xff0c;Spring还支持多种基…...

Python 中的作用域:规则与应用

在 Python 编程中&#xff0c;作用域&#xff08;Scope&#xff09; 是指一个变量可以被访问和引用的范围。作用域与变量的生命周期密切相关&#xff0c;决定了变量何时被创建、何时被销毁以及在哪些地方可以使用它。理解作用域对于编写清晰、可维护的代码至关重要。 Python 中…...

T-SQL语言的字符串处理

T-SQL语言的字符串处理 引言 在数据库管理和应用开发中&#xff0c;我们经常需要对字符串进行处理。字符串的处理包括查找、替换、分割、拼接以及格式化等操作&#xff0c;而这些操作在SQL Server中可以通过T-SQL&#xff08;Transact-SQL&#xff09;来实现。T-SQL是微软SQL…...

宇航用VIRTEX5系列FPGA的动态刷新方法及实现

SRAM型FPGA在宇航领域有广泛的应用&#xff0c;为解决FPGA在空间环境中的单粒子翻转问题&#xff0c;增强设计的可靠性&#xff0c;本文介绍一种低成本的抗辐照解决方案。该方案从外置高可靠存储器中读取配置数据&#xff0c;通过定时刷新结合三模冗余的方式消除单粒子影响&…...

Flink提交任务通过Kerberos认证

Flink提交任务通过Kerberos认证 Clouera官网地址&#xff1a; https://docs.cloudera.com/csa/1.7.0/security/topics/csa-securing-jobs.html Securing Apache Flink jobs flink run -d -p 2 \ -yD security.kerberos.login.keytabtest.keytab \ -yD security.kerberos.lo…...

【linux】文件与目录命令 - cp

文章目录 1. 基本用法2. 常用参数3. 用法举例4. 注意事项 cp 命令用于复制文件或目录&#xff0c;支持单个文件复制、多文件复制以及目录的递归复制&#xff0c;是 Linux 系统中常用的文件管理命令之一。 1. 基本用法 语法&#xff1a; cp [选项] 源文件 目标文件 cp [选项] …...

鸿蒙--登入案例

实现要求&#xff1a; 在账户和密码的输入框输入账号或密码时&#xff0c;提交按钮下方同步出现输入的账户和密码 Entry Component struct login {State username:string State password:string build() {Column(){// 图标Image($r(app.media.app_icon)).width(100).height(…...

【JavaWeb】EL表达式

目录 1.EL表达式概述 2.EL表达式运算 3.EL表达式操作对象 4.EL表达式内置对象 4.1.参数隐藏对象 4.2.域隐藏对象 4.3.PageContext对象 1.EL表达式概述 EL&#xff08;Expression Language&#xff09;是一门表达式语言&#xff0c;它对应<% ... %>。在JSP中&…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...