springboot创建并配置环境(一) - 创建环境
文章目录
- 一、介绍
- 二、启动环境Environment的分析
- 三、进入源码
- 四、创建环境
- 1. 如何确定应用类型
- 2. 测试
一、介绍
在springboot的启动流程中,启动环境Environment
是可以说是除了应用上下文ApplicationContext
之外最重要的一个组件了,而且启动环境为应用上下文提供了最基本的前提基础。
在启动环境中,主要保存大量配置信息和当前操作系统的配置信息以及环境变量。
对于它的重要性,我们可以这样理解:启动环境为创建应用上下文提供了基础支持,而应用上下文为我们开发springboot项目提供了基础支持。
本文基于以下版本进行展开:
- jdk:1.8
- springboot:2.4.3
另外:由于篇幅过长,决定分四集文章来讲解分析
一、springboot创建并配置环境(一) - 创建环境
二、springboot创建并配置环境(二) - 配置基础环境
三、springboot创建并配置环境(三) - 配置扩展属性(上集)
四、springboot创建并配置环境(四) - 配置扩展属性(下集)
二、启动环境Environment的分析
老规矩,在了解一个类之前,我们需要先通过其UML图对该类的功能有一个大致的了解,下面是启动环境Environment
的UML图:
-
PropertyResolver:顾名思义为属性解析器,提供用来解析并保存形如
key=value
这样的属性。 -
Environment:在
PropertyResolver
的基础上添加了对profile的支持,其实profile也是形如key=value
的属性配置,只是为了更清晰就把它做成独立的api了。 -
ConfigurablePropertyResolver:可配置的属性解析器。在
PropertyResolver
的基础上添加了类型转换器ConversionService
。 -
ConfigurableEnvironment:可配置的环境,即启动环境。本片文章主要就是围绕它来展开的。它对
Environment
做出了扩展,允许动态设置profile。并对其内部保存的属性集合进行分类,如:操作系统的属性、操作系统的环境变量。 -
ConfigurableWebEnvironment:在
ConfigurableEnvironment
的基础上添加了对servlet类型的web环境的支持。 -
ConfigurableReactiveWebEnvironment:在
ConfigurableEnvironment
的基础上添加了对响应式类型的web环境的支持。
从上图中不难看出,springboot为我们提供了三种启动环境
StandardEnvironment
:标准环境。提供基本的springboot启动环境。StandardServletEnvironment
:servlet类型的web环境。在标准环境的基础上,添加了对servlet类型的web环境的环境处理。StandardReactiveWebEnvironment
:响应式类型的web环境。在标准环境的基础上,添加了对响应式类型的web环境的环境处理。
三、进入源码
在springboot启动流程的源码中,我们不难发现,启动环境的创建和配置是在一个prepareEnvironment()
方法中完成的,如下所示:
进入该方法查看其实现逻辑:
本文主要围绕prepareEnvironment()
方法探讨springboot是如何创建运行环境并对其进行配置的。
下面进入正题。
四、创建环境
在prepareEnvironment()
方法中,getOrCreateEnvironment()
方法负责实例化环境对象,并将创建好的环境返回。所以我们需要进入该方法:
该方法很简单,就是根据当前应用类型去实例化对应的环境对象:
- 如果是servlet类型的web环境,则实例化一个
StandardServletEnvironment
对象 - 如果是响应式类型的web环境,则实例化一个
StandardReactiveWebEnvironment
对象 - 如果以上两种web环境都不是,则默认实例化一个标准环境对象
StandardEnvironment
。
但是,springboot是如何知道我们当前应用是哪一种类型呢?即webAppliicationType
是如何确定的?
1. 如何确定应用类型
当我们在springboot的主启动类中使用SpringApplicaton.run()
启动项目时,其内部其实是先创建一个SpringApplicaton
实例,然后对该实例调用其run()
方法,如下图所示
在创建SpringApplicaton
实例时,该构造方法内部确定当前应用程序类型并将该类型保存到webApplicationType
属性中,如下图所示
从该行代码可以看出,springboot通过调用WebApplicationType
的静态方法deduceFromClasspath()
,推断出当前应用程序类型。
我们再进入该静态方法来了解它是如何推断的
从该方法中看到,推断过程无非就是从类路径中判断是否存在指定的类
- 如果类路径中存在servlet相关的类,那么当前应用程序就是servlet类型的应用程序
- 如果类路径中仅存在reactive相关的类,那么当前应用程序就是响应式类型的应用程序
- 如果以上两种类都不存在,那么当前应用程序就什么类型的应用程序都不是了。
判断类路径中判断是否存在指定的类只需要调用ClassUtils的静态方法isPresent()
就行了。而在该静态方法中,则是通过对传入的类进行反射去实例化,如果实例化失败并抛出了异常,则说明该类是不存在的。
2. 测试
-
既不存在reactive相关的类,也不存在servlet相关的类
在pom中我们仅仅引入springboot的依赖
然后启动项目进入断点,查看当前应用程序的类型,确定为NONE类型的应用程序
-
仅存在reactive相关的类
在pom中我们引入springboot的依赖 和 reactive相关的依赖
然后启动项目进入断点,查看当前应用程序的类型,确定为响应式类型的应用程序
-
存在servlet相关的类
在pom中我们引入springboot的依赖 和 servlet相关的依赖
然后启动项目进入断点,查看当前应用程序的类型,确定为servlet类型的应用程序
点此进入下一集:springboot创建并配置环境(二) - 配置基础环境
纸上得来终觉浅,绝知此事要躬行。
————————我是万万岁,我们下期再见————————
相关文章:

springboot创建并配置环境(一) - 创建环境
文章目录 一、介绍二、启动环境Environment的分析三、进入源码四、创建环境1. 如何确定应用类型2. 测试 一、介绍 在springboot的启动流程中,启动环境Environment是可以说是除了应用上下文ApplicationContext之外最重要的一个组件了,而且启动环境为应用…...

2023JAVA 架构师面试 130 题含答案:JVM+spring+ 分布式 + 并发编程》...
此文包含 Java 面试的各个方面,史上最全,苦心整理最全 Java 面试题目整理包括基JVM算法数据库优化算法数据结构分布式并发编程缓存等,使用层面广,知识量大,涉及你的知识盲点。要想在面试者中出类拔萃就要比人付出更多的…...

layui手机端上传文件时返回404 Not Found的解决方案(client_body_temp权限设置)
关于 1.client_body_temp的作用 client_body_temp是一个指令指定保存客户端请求体临时文件的目录路径,以及是否进行缓存的配置指令。 在Web服务器中,当客户端向服务器发送请求时,请求体中包含了请求的主体部分,比如表单数据、上…...
网络编程知识
网络编程知识 一.网络七层模型 OSI模型: OSI 模型(Open System Interconnection model)是一个由国际标准化组织􏰁提出的概念模型,试图提供一个使各种不同的计算机和网络在世界范围内实现互联的标准框架。它将计算机网络体系结构划分为七层…...

线性神经网路——线性回归随笔【深度学习】【PyTorch】【d2l】
文章目录 3.1、线性回归3.1.1、PyTorch 从零实现线性回归3.1.2、简单实现线性回归 3.1、线性回归 线性回归是显式解,深度学习中绝大多数遇到的都是隐式解。 3.1.1、PyTorch 从零实现线性回归 %matplotlib inline import random import torch #d2l库中的torch模块&a…...
js实现多种按钮
你可以使用JavaScript来实现多种类型的按钮,以下是几个常见的示例: 普通按钮(Normal Button): <button>Click me</button> 带图标的按钮(Button with Icon): <bu…...
getopt函数(未更新完)
2023年7月28日,周五上午 这是我目前碰到过的比较复杂的函数之一, 为了彻底弄懂这个函数,我花了几个小时。 为了更好的说明这个函数,之后我可能会录制讲解视频并上传到B站, 如果我上传到B站,我会在文章添…...

SpringCloud学习路线(9)——服务异步通讯RabbitMQ
一、初见MQ (一)什么是MQ? MQ(MessageQueue),意思是消息队列,也就是事件驱动架构中的Broker。 (二)同步调用 1、概念: 同步调用是指,某一服务…...

postcss-pxtorem适配插件动态配置rootValue(根据文件路径名称,动态改变vue.config里配置的值)
项目背景:一个项目里有两个分辨率的设计稿(1920和2400),不能拆开来打包 参考: 是参考vant插件:移动端Vant组件库rem适配下大小异常的解决方案:https://github.com/youzan/vant/issues/1181 说明: 因为vue.c…...

代码随想录算法训练营第二十三天 | 额外题目系列
额外题目 1365. 有多少小于当前数字的数字借着本题,学习一下各种排序未看解答自己编写的青春版重点代码随想录的代码我的代码(当天晚上理解后自己编写) 941.有效的山脉数组未看解答自己编写的青春版重点代码随想录的代码我的代码(当天晚上理解后自己编写) 1207. 独一…...
UiAutomator
运行Espresso和UI Automator测试时要使用模拟器。国内手机的ROM大多进行过修改,可能加入很多限制,导致测试无法正常运行。 Espresso只支持一个活动内部交互行为的测试。跨越多个活动、多个应用的场景需要使用UI Automator。使用Espresso和UI Automator的…...
stm32标准库开发常用函数的使用和代码说明
文章目录 GPIO(General Purpose Input/Output)NVIC(Nested Vectored Interrupt Controller)DMA(Direct Memory Access)USART(Universal Synchronous/Asynchronous Receiver/Transmitter…...

有关合泰BA45F5260中断的思考
最近看前辈写的代码,发现这样一段代码: #ifdef SUPPORT_RF_NET_FUNCTION if(UART_INT_is_L()) { TmrInsertTimer(eTmrHdlUartRxDelay,TMR_PERIOD(2000),NULL); break; } #endif 其中UART_INT_is_L&am…...
Numpy-算数函数与数学函数
⛳算数函数 如果参与运算的两个对象都是ndarray,并且形状相同,那么会对位彼此之间进 第 30 页 行( - * /)运算。NumPy 算术函数包含简单的加减乘除: add(),subtract(),multiply() 和divide()。 …...
Nginx在springboot中起到的作用
面试时这样回答: 在Spring Boot项目中使用Nginx可以有以下用途: 1. 反向代理:Nginx可以作为反向代理服务器,将外部请求转发到后端的Spring Boot应用,并可以实现负载均衡、高可用、缓存等功能,提高系统的性…...

12.(开发工具篇vscode+git)vscode 不能识别npm命令
1:vscode 不能识别npm命令 问题描述: 解决方式: (1)右击VSCode图标,选择以管理员身份运行; (2)在终端中执行get-ExecutionPolicy,显示Restrictedÿ…...

如何在MacBook上彻底删除mysql
好久以前安装过,但是现在配置mysql一直出错,索性全部删掉重新配置。 一、停止MySQL服务 首先,请确保 MySQL 服务器已经停止运行,以免影响后续的删除操作。 sudo /usr/local/mysql/support-files/mysql.server stop如果你输入之…...
web攻击面试|网络渗透面试(一)
Web攻击面试大纲 常见Web攻击类型 1.1 SQL注入攻击 1.2 XSS攻击 1.3 CSRF攻击 1.4 命令注入攻击SQL注入攻击 2.1 基本概念 2.2 攻击原理 2.3 防御措施XSS攻击 3.1 基本概念 3.2 攻击原理 3.3 防御措施CSRF攻击 4.1 基本概念 4.2 攻击原理 4.3 防御措施命令注入攻击 5.1 基本概…...
VBA操作WORD(六)另存为不含宏的文档
Sub 另存为不含宏的文档()Application.DisplayAlerts False Application.ScreenUpdating FalseDim oDoc As DocumentSet oDoc Word.ActiveDocumentDim oRng As RangeSet oRng oDoc.ContentDim sPath As String默认存储路径,当前用户桌面,注释掉的是当…...
分享69个Java源码,总有一款适合您
Java源码 分享69个Java源码,总有一款适合您 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下...,大家下载后可以看到。 源码下载链接: https://pan.baidu.com/s/1ZgbJhMNwIyFyqFzHsDdL5w 提取码&a…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...