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

μC/OS-Ⅱ源码学习(3)---事件模型

快速回顾

μC/OS-Ⅱ中的多任务

μC/OS-Ⅱ源码学习(1)---多任务系统的实现

μC/OS-Ⅱ源码学习(2)---多任务系统的实现(下)

        本文开始,进入事件源码的学习。

事件模型

        在一个多任务系统里,各个任务在系统的统筹下相继执行,由于执行速度极快,就好像在一段时间内同时执行多个任务的代码一样,在更高级复杂的操作系统里,这叫做并发

        如果各个任务相互独立,没有资源的依赖和耦合,就可以凭借优先级的来决定先后执行的顺序,这是一种简单的多任务系统模型。但对于一块单片机来说,片上的资源(内存以及各种外设)是紧缺的,在完成需求的前提,可用的资源余量通常不多,这还只是平均余量,在复杂的应用场景下可能接近满载,此时各个任务就不能随心所欲的使用资源了,而是要按顺序依次排队等候使用(道理就是,即便空载也要保持这种编写习惯)。

        这种资源不仅是指硬件外设的使用,还体现在内存资源的使用上,一个简单的例子,当我们已经打开了某个文件时,若此时尝试在修改该文件的名称,会弹窗警示我们”该文件已被打开,请先关闭“。这是出于安全考虑,不希望多个进程同时对一个资源进行修改,而要有顺序地获取控制权。

        另一方面,各个任务之间还存在依赖关系,比如一个简单的热水器,包含ADC采样计算和PID逻辑输出两个任务(实际可能一个任务就行,这里仅作说明需要),那么后者一定会依赖前者提供实时数据进行新的运算,否则只能延续之前的输出。

        再比如一些任务,需要外设完成工作后产生中断,从而告知任务的运行(不能在中断内大量处理应用逻辑),这也是一种事件。

        从上面的各种案例场景分析,就知道需要各种各样的事件来协调大家的运行,才能在多任务环境下有条不紊的先后执行,减少应用出错的概率。在μC/OSⅡ中提供了五种不同的事件(EVENT)供用户使用(我归类为广义事件。另有系统定时器类型,但不归为事件):

//ucos_ii.h
#define  OS_EVENT_TYPE_UNUSED           0u
#define  OS_EVENT_TYPE_MBOX             1u   //邮箱
#define  OS_EVENT_TYPE_Q                2u   //队列
#define  OS_EVENT_TYPE_SEM              3u   //信号量
#define  OS_EVENT_TYPE_MUTEX            4u   //互斥信号量
#define  OS_EVENT_TYPE_FLAG             5u   //事件标志组
#define  OS_TMR_TYPE                  100u   //定时器

        事件有专门的事件控制块记录信息,其中邮箱(MBOX)队列(Q)信号量(SEM)互斥信号量(MUTEX)为狭义事件,其事件控制块类型为OS_EVENT,队列还有额外的控制块OS_Q事件标志组(FLAG)则是一类特殊的事件,有自己的控制块类型OS_FLAG_GRP

        它们分别装载在下面的全局变量中:

//ucos_ii.h
#if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0u)
OS_EXT  OS_EVENT     *OSEventFreeList;            /* 空白事件控制块链表 */
OS_EXT  OS_EVENT      OSEventTbl[OS_MAX_EVENTS];  /* 事件控制块数组 */
#endif#if (OS_Q_EN > 0u) && (OS_MAX_QS > 0u)
OS_EXT  OS_Q             *OSQFreeList;              /* 空白队列控制块链表 */
OS_EXT  OS_Q              OSQTbl[OS_MAX_QS];        /* 队列控制块数组 */
#endif#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
OS_EXT  OS_FLAG_GRP      OSFlagTbl[OS_MAX_FLAGS];   /* 事件标志组数组 */
OS_EXT  OS_FLAG_GRP     *OSFlagFreeList;            /* 空白的事件标志组链表  */
#endif

        由OS_EVENT_EN的定义也可以对事件进行分类了:

#define   OS_EVENT_EN   (((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) || (OS_MBOX_EN > 0u) || (OS_SEM_EN > 0u) || (OS_MUTEX_EN > 0u))

事件控制块类型

        从上一节描述可知,μC/OSⅡ共有三种事件控制块,分别是OS_EVENTOS_QOS_FLAG_GRP,其中OS_EVENT是用的最多的,这里先以它为例解读,后续讲到对应事件时再解析其它两种。

//ucos_ii.h
typedef struct os_event {INT8U    OSEventType;      /* 事件类型,有六种(其中一种是UNUSED) */void    *OSEventPtr;       /* OSEventPtr是一个多用途的指针,当作为链表时,可以指向下一个控制块;当作为具体的事件控制块时,指向具体的事件结构,如OS_Q */  INT16U   OSEventCnt;       /* 信号量计数器,其它事件类型不使用该成员 */OS_PRIO  OSEventGrp;       /* 等待信号的任务优先级组 */OS_PRIO  OSEventTbl[OS_EVENT_TBL_SIZE];  /* 等待信号的组内优先级 */#if OS_EVENT_NAME_EN > 0uINT8U   *OSEventName;      //事件名称
#endif
} OS_EVENT;

        其中,成员OSEventGrpOSEventTbl[OS_EVENT_TBL_SIZE]和多任务的就绪优先级逻辑类似,都是为了快速定位到最高优先级的就绪任务,为了之后对比和区分,之前多任务的部分我们称为”优先级就绪表“,在这里我们可以为其取名为”事件等待表“。

事件的初始化

        在执行OSInit()时,会对事件链表进行初始化,与任务控制块不同的是,事件链表为单相链表,具体函数为OS_InitEventList()

//os_core.c
static  void  OS_InitEventList (void)
{
#if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0u)
#if (OS_MAX_EVENTS > 1u)INT16U     ix;INT16U     ix_next;OS_EVENT  *pevent1;OS_EVENT  *pevent2;OS_MemClr((INT8U *)&OSEventTbl[0], sizeof(OSEventTbl));  /* 清空事件控制块数组 */for (ix = 0u; ix < (OS_MAX_EVENTS - 1u); ix++) {    /* 将OSEventTbl数组元素组成链表 */ix_next = ix + 1u;pevent1 = &OSEventTbl[ix];pevent2 = &OSEventTbl[ix_next];pevent1->OSEventType    = OS_EVENT_TYPE_UNUSED;    //初始化事件类型为UNUSEDpevent1->OSEventPtr     = pevent2;
#if OS_EVENT_NAME_EN > 0upevent1->OSEventName    = (INT8U *)(void *)"?";     /* 初始化事件名称"?" */
#endif}pevent1                         = &OSEventTbl[ix];pevent1->OSEventType            = OS_EVENT_TYPE_UNUSED;pevent1->OSEventPtr             = (OS_EVENT *)0;     //链表尾的下一个指针指向0
#if OS_EVENT_NAME_EN > 0upevent1->OSEventName            = (INT8U *)(void *)"?"; /* Unknown name                            */
#endifOSEventFreeList                 = &OSEventTbl[0];   //将空白链表头指向刚创建的链表
#elseOSEventFreeList                 = &OSEventTbl[0];       /* 只定义一个事件时,则链表也只有一个元素 */OSEventFreeList->OSEventType    = OS_EVENT_TYPE_UNUSED;OSEventFreeList->OSEventPtr     = (OS_EVENT *)0;
#if OS_EVENT_NAME_EN > 0uOSEventFreeList->OSEventName    = (INT8U *)"?";        /* 初始化事件名称"?" */
#endif
#endif
#endif
}

         还有事件标志组的初始化函数OS_FlagInit(),其内容和OS_InitEventList()基本一致,只是操作对象变了:

//os_flag.c
void  OS_FlagInit (void)
{
#if OS_MAX_FLAGS == 1u    /* 只设定一个事件标志组,则只需将OSFlagTbl首元素当作链表头 */OSFlagFreeList                 = (OS_FLAG_GRP *)&OSFlagTbl[0];OSFlagFreeList->OSFlagType     = OS_EVENT_TYPE_UNUSED;    //事件类型初始化为UNUSEDOSFlagFreeList->OSFlagWaitList = (void *)0;OSFlagFreeList->OSFlagFlags    = (OS_FLAGS)0;
#if OS_FLAG_NAME_EN > 0uOSFlagFreeList->OSFlagName     = (INT8U *)"?";
#endif
#endif#if OS_MAX_FLAGS >= 2uINT16U        ix;INT16U        ix_next;OS_FLAG_GRP  *pgrp1;OS_FLAG_GRP  *pgrp2;OS_MemClr((INT8U *)&OSFlagTbl[0], sizeof(OSFlagTbl));      /* 清空事件标志组控制块 */for (ix = 0u; ix < (OS_MAX_FLAGS - 1u); ix++) {        /* 初始化控制块并组成链表结构 */ix_next = ix + 1u;pgrp1 = &OSFlagTbl[ix];pgrp2 = &OSFlagTbl[ix_next];pgrp1->OSFlagType     = OS_EVENT_TYPE_UNUSED;    //事件类型初始化为UNUSEDpgrp1->OSFlagWaitList = (void *)pgrp2;
#if OS_FLAG_NAME_EN > 0upgrp1->OSFlagName     = (INT8U *)(void *)"?";     /* 事件标志组名称 */
#endif}pgrp1                 = &OSFlagTbl[ix]; pgrp1->OSFlagType     = OS_EVENT_TYPE_UNUSED;pgrp1->OSFlagWaitList = (void *)0;      //最后一个元素的下一个指针指向0
#if OS_FLAG_NAME_EN > 0upgrp1->OSFlagName     = (INT8U *)(void *)"?";             
#endifOSFlagFreeList        = &OSFlagTbl[0];
#endif

         除此之外,还有队列控制块的初始化OS_QInit()

//os_q.c
void  OS_QInit (void)
{
#if OS_MAX_QS == 1u      /* 只设定一个队列时 */OSQFreeList         = &OSQTbl[0];          OSQFreeList->OSQPtr = (OS_Q *)0;
#endif#if OS_MAX_QS >= 2uINT16U   ix;INT16U   ix_next;OS_Q    *pq1;OS_Q    *pq2;OS_MemClr((INT8U *)&OSQTbl[0], sizeof(OSQTbl));  /* 清空队列控制块 */for (ix = 0u; ix < (OS_MAX_QS - 1u); ix++) {     /* 初始化队列控制块,并组成链表 */ix_next = ix + 1u;pq1 = &OSQTbl[ix];pq2 = &OSQTbl[ix_next];pq1->OSQPtr = pq2;}pq1         = &OSQTbl[ix];pq1->OSQPtr = (OS_Q *)0;OSQFreeList = &OSQTbl[0];
#endif
}

         接下来将具体解析各种事件的生命周期函数源码。

相关文章:

μC/OS-Ⅱ源码学习(3)---事件模型

快速回顾 μC/OS-Ⅱ中的多任务 μC/OS-Ⅱ源码学习(1)---多任务系统的实现 μC/OS-Ⅱ源码学习(2)---多任务系统的实现(下) 本文开始&#xff0c;进入事件源码的学习。 事件模型 在一个多任务系统里&#xff0c;各个任务在系统的统筹下相继执行&#xff0c;由于执行速度极快&a…...

Jmeter进阶篇(30)深入探索 JMeter 监听器

前言 在性能测试领域里,Apache JMeter 是一款经典而强大的工具,而其中的监听器(Listeners)组件更是发挥着不可或缺的关键作用。 监听器就像敏锐的观察者,默默记录测试执行过程中的各种数据,作为系统性能分析的数据依据。 本文将带你全方位走进 JMeter 监听器的奇妙世界,…...

虚幻引擎的工程目录结构

虚幻引擎的工程目录结构如下&#xff1a; .idea/.vs&#xff1a;用于IDE&#xff08;如IntelliJ IDEA或Visual Studio&#xff09;的项目配置文件&#xff0c;包含工程设置和解决方案文件。 Binaries&#xff1a;存放编译后的可执行文件和相关的动态链接库&#xff08;DLL&…...

深度学习中的yield

以下为例&#xff1a; def data_iter(batch_size, features, labels):num_examples len(features)indices list(range(num_examples))# 这些样本是随机读取的&#xff0c;没有特定的顺序random.shuffle(indices)for i in range(0, num_examples, batch_size):batch_indices …...

数据库数据恢复—ORACLE常见故障有哪些?如何恢复数据?

Oracle数据库常见故障表现&#xff1a; 1、ORACLE数据库无法启动或无法正常工作。 2、ORACLE ASM存储破坏。 3、ORACLE数据文件丢失。 4、ORACLE数据文件部分损坏。 5、ORACLE DUMP文件损坏。 Oracle数据库数据恢复方案&#xff1a; 1、检测存放数据库的服务器/存储设备是否存…...

使用JavaScrip和HTML搭建一个简单的博客网站系统

搭建一个简单的博客网站系统&#xff0c;我们需要创建几个基本的页面和功能&#xff1a;登录、注册、文章发布等。这里我们先实现一个基础版本&#xff0c;包括用户登录、注册以及文章发布的功能。由于这是一个简化版的示例&#xff0c;我们将所有逻辑集成在一个HTML文件中&…...

算法-字符串-76.最小覆盖子串

一、题目 二、思路解析 1.思路&#xff1a; 滑动窗口&#xff01;&#xff01;&#xff01; 2.常用方法&#xff1a; 无 3.核心逻辑&#xff1a; 1.特殊情况&#xff1a;s或t是否为空字符串 if(snull||tnull)return ""; 2.声明一个字符数组——用于记录对应字符出现…...

Python爬虫之Selenium的应用

【1】Selenium基础介绍 1.什么是selenium&#xff1f; &#xff08;1&#xff09;Selenium是一个用于Web应用程序测试的工具。 &#xff08;2&#xff09;Selenium 测试直接运行在浏览器中&#xff0c;就像真正的用户在操作一样。 &#xff08;3&#xff09;支持通过各种driv…...

粉丝生产力与开源 AI 智能名片 2+1 链动模式商城小程序的融合创新与价值拓展

摘要&#xff1a;本文聚焦于粉丝生产力在当代文化与商业语境中的独特作用&#xff0c;并深入探讨其与开源 AI 智能名片 21 链动模式商城小程序的有机结合。通过剖析粉丝生产力的多元表现形式、内在驱动机制以及开源 AI 智能名片 21 链动模式商城小程序的功能特性与商业潜力&…...

红黑树(Red-Black Tree)

一、概念 红黑树&#xff08;Red Black Tree&#xff09;是一种自平衡的二叉搜索树&#xff0c;通过添加颜色信息来确保在进行插入和删除操作时&#xff0c;树的高度保持在对数级别&#xff0c;从而保证了查找、插入和删除操作的时间复杂度为 O(log n)。这种树可以很好地解决普…...

Cocos 资源加载(以Json为例)

resources 通常我们会把项目中需要动态加载的资源放在 resources 目录下&#xff0c;配合 resources.load 等接口动态加载。你只要传入相对 resources 的路径即可&#xff0c;并且路径的结尾处 不能 包含文件扩展名。 resources.load("Inf", JsonAsset, (error, ass…...

解决 IntelliJ IDEA 启动错误:插件冲突处理

引言 在使用 IntelliJ IDEA 进行开发时&#xff0c;我们可能会遇到各种启动错误。本文将详细介绍一种常见的错误&#xff1a;插件冲突&#xff0c;并提供解决方案。 错误背景 最近&#xff0c;有用户在启动 IntelliJ IDEA 时遇到了一个错误&#xff0c;提示信息为&#xff1a…...

SQL——DQL分组聚合

分组聚合&#xff1a; 格式&#xff1a; select 聚合函数1(聚合的列),聚合函数2(聚合的列) from 表名 group by 标识列; ###若想方便分辨聚合后数据可在聚合函数前加上标识列&#xff08;以标识列进行分组&#xff09; 常见的聚合函数: sum(列名):求和函数 avg(列名)…...

Ripro V5日主题 v8.3 开心授权版 wordpress主题虚拟资源下载站首选主题模板

RiPro主题全新V5版本&#xff0c;是一个优秀且功能强大、易于管理、现代化的WordPress虚拟资源商城主题。支持首页模块化布局和WP原生小工具模块化首页可拖拽设置&#xff0c;让您的网站设计体验更加舒适。同时支持了高级筛选、自带会员生态系统、超全支付接口等众多功能&#…...

分布式搜索引擎之elasticsearch基本使用2

分布式搜索引擎之elasticsearch基本使用2 在分布式搜索引擎之elasticsearch基本使用1中&#xff0c;我们已经导入了大量数据到elasticsearch中&#xff0c;实现了elasticsearch的数据存储功能。但elasticsearch最擅长的还是搜索和数据分析。 所以j接下来&#xff0c;我们研究下…...

java学习-第十五章-IO流(java.io包中)

一、理解 1. 简单而言&#xff1a;流就是内存与存储设备之间传输数据的通道、管道。 2. 分类&#xff1a; (1) 按方向(以JVM虚拟机为参照物)【重点】 输入流&#xff1a;将中的内容读入到中。 输出流&#xff1a;将中的内容写入到中。 (2) 按单位&#xff1a; 字节流&#xf…...

企业如何实现数据从源端到消费端的全链路加工逻辑可视化?

要想实现数据加工链路的可视化&#xff0c;血缘图谱无疑是一个有效的工具。血缘图谱能够清晰地展示数据从产生、流转、加工到最终消费的每一个环节&#xff0c;帮助企业直观地理解数据之间的关联和依赖关系&#xff0c;轻松追溯数据来源和去向&#xff0c;并在数据出现问题时快…...

Toxicity of the Commons: Curating Open-Source Pre-Training Data

基本信息 &#x1f4dd; 原文链接: https://arxiv.org/abs/2410.22587&#x1f465; 作者: Catherine Arnett, Eliot Jones, Ivan P. Yamshchikov, Pierre-Carl Langlais&#x1f3f7;️ 关键词: toxicity filtering, language models, data curation&#x1f4da; 分类: 机器…...

Python 单例模式工厂模式和classmethod装饰器

前言&#xff1a; Python作为面向对象的语言&#xff0c;显然支持基本的设计模式。也具备面向对象的语言的基本封装方法&#xff1a;属性、方法、继承、多态等。但是&#xff0c;做为强大的和逐渐发展的语言&#xff0c;python也有很多高级的变种方法&#xff0c;以适应更多的…...

计算机键盘简史 | 键盘按键功能和指法

注&#xff1a;本篇为 “计算机键盘简史 | 键盘按键功能和指法” 相关文章合辑。 英文部分机翻未校。 The Evolution of Keyboards: From Typewriters to Tech Marvels 键盘的演变&#xff1a;从打字机到技术奇迹 Introduction 介绍 The keyboard has journeyed from a humb…...

【数字信号处理】期末综合实验,离散时间信号与系统的时域分析,离散信号 Z 变换,IIR 滤波器的设计与信号滤波,用窗函数法设计 FIR 数字滤波器

关注作者了解更多 我的其他CSDN专栏 过程控制系统 工程测试技术 虚拟仪器技术 可编程控制器 工业现场总线 数字图像处理 智能控制 传感器技术 嵌入式系统 复变函数与积分变换 单片机原理 线性代数 大学物理 热工与工程流体力学 数字信号处理 光电融合集成电路…...

面试技术点之安卓篇

一、基础 二、高级 三、组件 Android中SurfaceView和TextureView有什么区别&#xff1f; 参考 Android中SurfaceView和TextureView有什么区别&#xff1f; 四、三方框架 五、系统源码 六、性能优化...

Windows Terminal ssh到linux

1. windows store安装 Windows Terminal 2. 打开json文件配置 {"$help": "https://aka.ms/terminal-documentation","$schema": "https://aka.ms/terminal-profiles-schema","actions": [{"command": {"ac…...

自适应卡尔曼滤波(包括EKF、UKF、CKF等)的创新思路——该调什么、不该调什么

在调节自适应卡尔曼滤波时&#xff0c;需要注意的参数和矩阵都对滤波器的性能有直接影响。本文给出详细的说明&#xff0c;包括相关公式和 MATLAB 代码示例 文章目录 需要调节的参数1. **过程噪声协方差矩阵 Q Q Q**&#xff1a;2. **测量噪声协方差矩阵 R R R**&#xff1a;…...

SpringBoot项目监听端口接受数据(NIO版)

文章目录 前言服务端相关配置核心代码 客户端 前言 环境&#xff1a; JDK&#xff1a;64位 Jdk1.8 SpringBoot&#xff1a;2.1.7.RELEASE 功能&#xff1a; 使用Java中原生的NIO监听端口接受客户端的数据&#xff0c;并发送数据给客户端。 服务端 相关配置 application.ym…...

QT实战--带行号的支持高亮的编辑器实现(2)

本文主要介绍了第二种实现带行号的支持高亮的编辑器的方式,基于QTextEdit实现的,支持自定义边框,背景,颜色,以及滚动条样式,支持输入变色,复制文本到里面变色,支持替换,是一个纯专业项目使用的编辑器 先上效果图: 1.头文件ContentTextEdit.h #ifndef CONTENT_TEXT_…...

(翻译)网络安全书籍推荐列表

注&#xff1a;对于所有的书籍链接&#xff0c;我都会寻找中文版重新链接&#xff0c;如无中文版&#xff0c;则按原文链接英文版。并且所有书籍名称保留英文名称 这是一个我建立的一个有关计算机安全的书籍列表&#xff0c;它们都是很有用的“计算机安全”这个主题的相关数据。…...

TcpServer 服务器优化之后,加了多线程,对心跳包进行优化

TcpServer 服务器优化之后&#xff0c;加了多线程&#xff0c;对心跳包进行优化 TcpServer.h #ifndef TCPSERVER_H #define TCPSERVER_H#include <iostream> #include <winsock2.h> #include <ws2tcpip.h> #include <vector> #include <map> #…...

黑马程序员Java项目实战《苍穹外卖》Day12

苍穹外卖-day12 课程内容 工作台Apache POI导出运营数据Excel报表 功能实现&#xff1a;工作台、数据导出 工作台效果图&#xff1a; 数据导出效果图&#xff1a; 在数据统计页面点击数据导出&#xff1a;生成Excel报表 1. 工作台 1.1 需求分析和设计 1.1.1 产品原…...

经纬度解析到省市区【开源】

现在业务中有需要解析经纬度到省市区。 按理说可以直接使用高德&#xff0c;百度之类的。 但是老板太抠。于是去找开源项目。找了一圈&#xff0c;数据都太老了&#xff0c;而且有时候编码还不匹配。 所以诞生了这个项目&#xff0c;提供完整的一套省市区编码和定位反解析。…...

360网站怎么建设/搜索引擎入口大全

一 应用场景描述现在我需要向50数量的服务器分发Logstash新版本的rpm包&#xff0c;大概220MB左右&#xff0c;直接使用Ansible的copy命令进行传输&#xff0c;命令如下&#xff1a;ansible all -m copy -a "src/opt/software/logstash/logstash-agent-2.3.3-fb.centos6.…...

温州做网站的企业/市场营销是做什么的

从左到右依次排列&#xff0c;如果出现重复值&#xff0c;则按照右侧的排序规则进行排序&#xff1b; 例如&#xff1a;分数倒序排序&#xff0c;但是遇到重复值&#xff0c;则再按照class_id倒序排 例如&#xff1a;分数倒序排序&#xff0c;没有重复值&#xff0c;进行了正常…...

成都医院手机网站建设/兰州seo优化公司

无意间发现之前搭建MySQL的时候&#xff0c;有将操作过程记录下来&#xff0c;涉及主机系统配置修改&#xff0c;MySQL用户和目录创建&#xff0c;初始化等操作。未免日后遗忘&#xff0c;特保存在这里。有些步骤可能会有错&#xff0c;需要甄别。注&#xff1a;mysql-5.7.91、…...

能连接wordpress的app/广东网络优化推广

新建一单文档滚动视图AppExe。源文件链接 doc类添加变量 public:int ReadImage(LPCTSTR lpszPathName);int imageWidth,imageHeight; //滚动视图大小BITMAPINFO * lpbmi; //bmp显示缓存&#xff0c;必需IplImage* m_pImage; //图像指针 变量初始化 CImageProcessDoc::CIm…...

网站风格分类/今日国内最新新闻

分享一下我老师大神的人工智能教程&#xff01;零基础&#xff0c;通俗易懂&#xff01;http://blog.csdn.net/jiangjunshow也欢迎大家转载本篇文章。分享知识&#xff0c;造福人民&#xff0c;实现我们中华民族伟大复兴&#xff01;<pre name"code" class"s…...

实时新闻/seo权重优化软件

简介在早前的博客中曾经写过 Spring 程序通过 Bean 映射实现配置信息的读取。 在SpringBoot 框架中读取配置的方式变得非常多样&#xff0c;这导致读者在搜寻资料时反而容易迷糊。到底&#xff0c;SpringBoot 是按什么顺序加载配置&#xff1f;相应的&#xff0c;我们该选择什么…...