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

Spring Boot自动配置原理解析

文章目录

  • 前言
  • 一、@SpringBootConfiguration
  • 二、@EnableAutoConfiguration
    • 2.1、@AutoConfigurationPackage
    • 2.2、@Import(AutoConfigurationImportSelector.class)
  • 三、@ComponentScan
  • 四、自动配置源码
    • 4.1、获取所有候选的自动配置类
    • 4.2、过滤不满足条件的自动配置
  • 总结


前言

  在常规的SSM项目中,通常需要用户自己去进行Spring、Spring MVC、Mybatis的整合,以及Tomcat的配置。而在Spring Boot项目中,整合工作已经由Spring Boot去完成,通常我们会引入:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

  的依赖,在spring-boot-starter-web中就已经完成了Spring、Spring MVC、Tomcat的整合,通常被称为自动配置
在这里插入图片描述  而完成自动配置的关键,在于启动类上的@SpringBootApplication注解:
在这里插入图片描述

  @SpringBootApplication是一个复合注解,其中包含了@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan
在这里插入图片描述

一、@SpringBootConfiguration

  @SpringBootConfiguration注解,没什么好说的,主要作用是将标注了该注解的类标记为配置类(通常是启动类),并且该配置类还会作为一个Bean放入Spring容器中。
在这里插入图片描述  @Configuration注解包含了@Component
在这里插入图片描述

二、@EnableAutoConfiguration

  @EnableAutoConfiguration是三个注解中最重要的一个,自动配置的源码就在该注解中有所体现,它也是一个复合注解,包含了@AutoConfigurationPackage@Import
在这里插入图片描述

2.1、@AutoConfigurationPackage

  @AutoConfigurationPackage上使用了@Import注解,导入了AutoConfigurationPackages类,当执行该类的register方法时(执行时机:Spring的refresh方法扫描配置类并解析时),会尝试向bean定义中注册一个类型为BasePackagesBeanDefinition的Bean,其中的basePackages属性存放的就是当前配置类所在的包路径。
在这里插入图片描述  该包路径可以给其他jar包使用,例如MyBatis的扫描逻辑。

2.2、@Import(AutoConfigurationImportSelector.class)

  在@EnableAutoConfiguration中,还使用@Import注解去导入了AutoConfigurationImportSelector类,该类中的逻辑是自动配置的关键:
在这里插入图片描述  AutoConfigurationImportSelector类实现了DeferredImportSelector接口。DeferredImportSelector从名称上看,似乎是在ImportSelector的基础上增加了延迟的功能,实际上DeferredImportSelector也是继承了ImportSelector
在这里插入图片描述  为什么要实现DeferredImportSelector接口?先看一个案例,这个案例的目的是进行条件装配,假如项目中没有自定义的User对象,就在配置类中创建一个User。

public class RagdollCatConfiguration {@Bean@ConditionalOnMissingBean(User.class)public User user(){return new User("从RagdollCatConfiguration创建");}
}
public class RagdollCatImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"com.itbaima.boot.RagdollCatConfiguration"};}
}
@SpringBootApplication
@Import(RagdollCatImportSelector.class)
public class StartApplication {@Beanpublic User user(){return new User("从StartApplication创建");}public static void main(String[] args) {SpringApplication.run(StartApplication.class,args);}
}

  预期的结果是,控制台打印从RagdollCatConfiguration创建。但是最终的结果是报错:
在这里插入图片描述  原因在于Spring的refresh方法中,解析配置文件的顺序问题:
在这里插入图片描述解析@Import注解

  在ConfigurationClassParser#processImports中,因为案例中的RagdollCatImportSelector 没有实现DeferredImportSelector接口,所以走的是else的逻辑,即执行RagdollCatImportSelector 的select方法,拿到配置类路径,然后解析配置类RagdollCatConfiguration 的内容。
在这里插入图片描述  也就是说,RagdollCatConfiguration 中的代码,会先于StartApplication 中的执行,而在执行RagdollCatConfiguration 中的条件装配时,Spring容器中肯定是没有User的,在这里就会创建。而在StartApplication 中尝试再次将User注册成Bean,就会出现上面的错误。

  这样的结果很明显不符合预期,我们是希望用户自定义Bean的优先级,要高于Spring Boot条件装配的优先级。解决的方法在上图中也有所体现,即实现DeferredImportSelector接口:

public class RagdollCatImportSelector implements DeferredImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"com.itbaima.boot.RagdollCatConfiguration"};}
}

  最终的效果是用户自定义的Bean先于Spring Boot的条件装配执行:

在这里插入图片描述


  但是在AutoConfigurationImportSelector中,执行的并非是selectImports的逻辑。
在这里插入图片描述  因为该类同时还重写了getImportGroup方法:
在这里插入图片描述  实际执行的是AutoConfigurationGroupprocess方法:
在这里插入图片描述  而process方法,最终同样会调用到selectImports中的getAutoConfigurationEntry方法,该方法是自动配置的核心方法

三、@ComponentScan

  @ComponentScan是进行路径扫描的注解,如果没有指定路径,默认是扫描标注了@ComponentScan注解的类,所在包下的所有类。而重点要看的是其中的两个排除条件:
在这里插入图片描述  第一个排除条件,是用户自定义了实现TypeExcludeFilter的类,然后重写了其中的match方法:
在这里插入图片描述

public class MyACI implements ApplicationContextInitializer {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {applicationContext.getBeanFactory().registerSingleton("typeExcludeFilter",new TypeExcludeFilter(){@Overridepublic boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {return metadataReader.getClassMetadata().getClassName().equals("com.itbaima.boot.User");}});}
}

  满足条件即被排除:
在这里插入图片描述
  第二个排除条件,是排除掉自动配置类:
在这里插入图片描述

四、自动配置源码

  selectImports中的getAutoConfigurationEntry方法是自动配置的核心源码:

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {// 1. 检查 @EnableAutoConfiguration 是否启用if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY;}// 2. 获取 @EnableAutoConfiguration 注解的属性(如果有的话)AnnotationAttributes attributes = getAttributes(annotationMetadata);// 3. 获取所有候选的自动配置类(从 META-INF/spring.factories 或 AutoConfiguration.imports 加载)List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);// 4. 去重,防止重复加载configurations = removeDuplicates(configurations);// 5. 获取所有被排除的自动配置类(@EnableAutoConfiguration(exclude = xxx.class) 或 spring.autoconfigure.exclude 配置)Set<String> exclusions = getExclusions(annotationMetadata, attributes);// 6. 校验是否有错误的排除类(比如排除的类根本不存在)checkExcludedClasses(configurations, exclusions);// 7. 从候选配置中移除排除的配置类configurations.removeAll(exclusions);// 8. 过滤不满足条件的自动配置(基于 @ConditionalOnClass、@ConditionalOnProperty 等条件)configurations = getConfigurationClassFilter().filter(configurations);// 9. 触发自动配置导入事件(给监听器用)fireAutoConfigurationImportEvents(configurations, exclusions);// 10. 返回最终的自动配置类列表return new AutoConfigurationEntry(configurations, exclusions);
}

  重点看一下其中的3和8。

4.1、获取所有候选的自动配置类

  Spring Boot是如何知道那些jar包需要自动装配的?首先在getCandidateConfigurations方法中,会从spring.factories文件中获取所有的自动配置类(也会获取自己项目中定义的spring.factories文件中的,以及第三方jar包中META-INF的spring.factories):
在这里插入图片描述spring.factories  spring-boot-autoconfigure中的spring.factories:
在这里插入图片描述  点进去发现都是一些条件装配类。重点看类上的@ConditionalOnClass注解。只有当前项目的依赖中有@ConditionalOnClass注解标注的类,该配置才会生效,这些类都是对应依赖项的核心类。(例如下图,只有项目中引入了RabbitMQ 相关的依赖,它才会生效)
在这里插入图片描述  但是在获取所有候选的自动配置类这一步,会拿到全量的:
在这里插入图片描述

4.2、过滤不满足条件的自动配置

  在fliter方法中,拿到三个默认的filter,调用match方法进行条件匹配:
在这里插入图片描述  对于4.1中拿到的所有自动配置类,进行条件匹配:
在这里插入图片描述  在进行类条件匹配时,还会去开启多线程执行:
在这里插入图片描述  在这里才会真正去执行spring.factories中具体每个配置项的@ConditionalOnClass等条件装配注解的匹配,会过滤掉项目中没有对应依赖的配置项。
在这里插入图片描述

总结

  Spring Boot的@SpringBootApplication是一个复合注解,包含了:

  • @SpringBootConfiguration:标记当前类是配置类,并且将当前类加入Spring 容器。
  • @EnableAutoConfiguration:将当前类所在的包路径注册到bean定义,并且进行自动配置。(实现了DeferredImportSelector接口,以用户自定义的bean优先。)
  • @ComponentScan:默认扫描当前类所在的包下的所有类。两个排除条件:实现了TypeExcludeFilter接口,重写的match方法的逻辑,以及其他自定义的自动配置类。

  即:标注了@SpringBootApplication的类,自身就作为Spring 的配置类。Spring会去扫描该类所在的包下的所有类。当然@SpringBootApplication也可以不标注在启动类上。并且Spring Boot 自动配置的实现,依靠:

  • META-INF下的spring.factories文件(自身以及第三方jar包的,可以称为SPI机制)
  • 条件装配,@ConditionalOnClass等注解。

  同时在@ConditionalOnClass的实现中,进行条件装配还会开启多线程执行(2个线程),提高效率。

相关文章:

Spring Boot自动配置原理解析

文章目录 前言一、SpringBootConfiguration二、EnableAutoConfiguration2.1、AutoConfigurationPackage2.2、Import(AutoConfigurationImportSelector.class) 三、ComponentScan四、自动配置源码4.1、获取所有候选的自动配置类4.2、过滤不满足条件的自动配置 总结 前言 在常规的…...

LlamaIndex实现(基于PDF|CSV文件)RAG检索增强生成:NaiveRAG

什么是 RAG&#xff1f; RAG&#xff08;Retrieval-Augmented Generation&#xff0c;检索增强生成&#xff09; 是一种结合 信息检索&#xff08;Retrieval&#xff09; 和 文本生成&#xff08;Generation&#xff09; 的AI技术&#xff0c;用于提升大语言模型&#xff08;L…...

分布式系统面试总结:3、分布式锁(和本地锁的区别、特点、常见实现方案)

仅供自学回顾使用&#xff0c;请支持javaGuide原版书籍。 本篇文章涉及到的分布式锁&#xff0c;在本人其他文章中也有涉及。 《JUC&#xff1a;三、两阶段终止模式、死锁的jconsole检测、乐观锁&#xff08;版本号机制CAS实现&#xff09;悲观锁》&#xff1a;https://blog.…...

vue3搭建实战项目笔记三

vue3搭建实战项目笔记三 3.1.行高偏移问题3.2.谷歌浏览器上不能定位3.2.2 移动端css隐藏滚动条 3.3.获取列表的数据3.3.1 服务器返回十万条数据3.3.2 分页展示数据3.3.2 防止展示数据为空报错 3.4.上拉加载数据3.4.1 加载更多数据3.4.2 监听页面滚动到底部3.4.3 监听滚动的时机…...

【商城实战(101)】电商未来已来:新技术引领商城发展新航向

【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配,乃至运营推广策略,102 章内容层层递进。无论是想…...

深入解析最大公约数(GCD)与最小公倍数(LCM)的C++实现

深入解析最大公约数&#xff08;GCD&#xff09;与最小公倍数&#xff08;LCM&#xff09;的C实现 一、GCD与LCM的数学定义 1. 最大公约数&#xff08;GCD&#xff09; 两个或多个整数共有约数中最大的一个。 例如&#xff1a; GCD(12, 18) 6GCD(21, 14) 7 2. 最小公倍数…...

低功耗LPWAN模块开发指南:远距离无线通信与边缘计算融合实战‌

在远程资产追踪、野外环境监测等场景中&#xff0c;稳定可靠的长距离通信与超低功耗是系统设计的核心挑战。eFish-SBC-RK3576通过 ‌原生双UART接口 USB OTG扩展能力‌ &#xff0c;可无缝集成主流LPWAN模组&#xff08;LoRa/NB-IoT&#xff09;&#xff0c;实现“数据采集-边…...

【质量管理】纠正、纠正措施和预防的区别与解决问题的四重境界

“质量的定义就是符合要求”&#xff0c;我们在文章【质量管理】人们对于质量的五个错误观念-CSDN博客中提到过&#xff0c;这也是质量大师克劳士比所说的。“质量的系统就是预防”&#xff0c;防止出现产品不良而造成的质量损失。 质量问题的解决可以从微观和宏观两个方面来考…...

STM32F103_LL库+寄存器学习笔记12 - 提高串口通讯程序的健壮性:异常监控 + 超时保护机制

导言 首先&#xff0c;进行USART和DMA状态监测、记录异常状态并主动处理&#xff0c;是高健壮性嵌入式系统开发的核心思想之一。 这种机制看似复杂&#xff0c;实则能有效保障系统长期、稳定地运行&#xff1a; 提升通讯可靠性。降低维护成本。增强系统自恢复能力。 因此&…...

搜索-BFS

马上蓝桥杯了&#xff0c;最近刷了广搜&#xff0c;感觉挺有意思的&#xff0c;广搜题类型都差不多&#xff0c;模板也一样&#xff0c;大家写的时候可以直接套模板 这里给大家讲一个比较经典的广搜题-迷宫 题目问问能否走到 (n,m) 位置&#xff0c;假设最后一个点是我们的&…...

Keil调试(RTT Debug 断点)

调试 打印操作 方式接口优缺点串口打印TXRX简单,但是占用串口,速度慢,重定向fputc简单RTT打印SWDIOSWCLK速度快,不占额外接口,直接移植RTT库断点打印SWDIOSWCLKDebug的时候断点操作SWOSWDIOSWCLKSWO需要连接SWO引脚,重定向fputc简单 这里我只介绍RTT打印和断点打印; 一. RT…...

【jQuery】插件

目录 一、 jQuery插件 1. 瀑布流插件&#xff1a; jQuery 之家 http://www.htmleaf.com/ 2. 图片懒加载&#xff1a; jQuery 插件库 http://www.jq22.com/ 3. 全屏滚动 总结不易~ 本章节对我有很大收获&#xff0c;希望对你也是~~~ 一、 jQuery插件 jQuery 功能…...

leetcode 28 Find the Index of the First Occurrence in a String

直接用kmp算法 class Solution { public:int strStr(string haystack, string needle) {return kmp(haystack,needle);}int kmp(std::string &text,std::string &pattern){int n text.size();int m pattern.size();if(m 0)return 0;std::vector<int> next;ne…...

nginx 动静分离

一.动静分离 1.动静分离的好处 Apache Tocmat 严格来说是一款java EE服务器&#xff0c;主要是用来处理 servlet请求。处理css、js、图片这些静态文件的IO性能不够好&#xff0c;因此&#xff0c;将静态文件交给nginx处理&#xff0c;可以提高系统的访问速度&#xff0c;减少…...

1.2 斐波那契数列模型:LeetCode 面试题 08.01. 三步问题

动态规划解三步问题&#xff1a;LeetCode 面试题 08.01. 三步问题 1. 题目链接 LeetCode 面试题 08.01. 三步问题 题目要求&#xff1a;小孩上楼梯&#xff0c;每次可以走1、2或3步&#xff0c;计算到达第 n 阶台阶的不同方式数&#xff0c;结果需对 1e9 7 取模。 2. 题目描述…...

关于AutoMapper

AutoMapper 概述 AutoMapper 是一个基于约定的对象 - 对象映射库&#xff0c;主要用于在不同对象类型之间自动映射属性值。它能根据配置的映射规则&#xff0c;将源对象的属性值填充到目标对象中&#xff0c;避免了手动编写大量繁琐的对象映射代码。 作用 提升开发效率&…...

是否每一层之间都要线性变换和激活函数?

1. 神经网络层的基本组成 一个典型的神经网络层通常包含两个步骤&#xff1a; 线性变换&#xff08;加权求和&#xff09;&#xff1a; z Wx} b 其中W 是权重矩阵&#xff0c;b是偏置向量&#xff0c;是输入&#xff0c;z 是线性输出。激活函数&#xff1a; 其中&#xff0c…...

golang 的reflect包的常用方法

目录 reflect 包方法总结 类型 (Type) 方法 值 (Value) 方法 代码示例&#xff1a; reflect 包方法总结 p : Person{Name: "小明", Age: 22}t : reflect.TypeOf(&p)v : reflect.ValueOf(p) 类型 (Type) 方法 方法名描述示例               Na…...

CentOS 7 安装 EMQX (MQTT)

CentOS 7 安装 EMQX 通过 Yum 源安装 EMQX 支持通过 Yum 源安装&#xff0c;您可通过以下 Yum 命令从中自动下载和安装 EMQX。 通过以下命令配置 EMQX Yum 源&#xff1a; curl -s https://assets.emqx.com/scripts/install-emqx-rpm.sh | sudo bash安装以下依赖项&#xff…...

Flask项目部署:Flask + uWSGI + Nginx

目录 1,网络架构 2,环境安装 2.1,安装yum:Shell软件包管理器 2.2 安装python 2.3 安装uWSGI 2.4 安装Flask 3,上传工程包到服务器,打包Flask项目 4,创建和配置 uwsgi 配置文件 uwsgi.ini 4.1配置文件 4.2配置文件注释详解 5,启动服务 6,安装nginx 7,nginx配置 8,…...

软件工程面试题(十五)

1、servlet 创建过程以及ruquest,response,session的生命周期? Servlet的创建过程: 第一步 public class AAA extends HttpServlet{ 实现对应的doxxx方法 } 第二步: 在web.xml中配置 <servlet> <servlet-name></servlet-name> <servlet-c…...

当Kafka化身抽水马桶:论组件并发提升与系统可用性的量子纠缠关系

《当Kafka化身抽水马桶&#xff1a;论组件并发提升与系统可用性的量子纠缠关系》 引言&#xff1a;一场OOM引发的血案 某个月黑风高的夜晚&#xff0c;监控系统突然发出刺耳的警报——我们的数据发现流水线集体扑街。事后复盘发现&#xff1a;Kafka集群、Gateway、Discovery服…...

python和Java的区别

Python和Java是两种流行的编程语言&#xff0c;它们之间有一些重要的区别&#xff1a; 语法&#xff1a;Python是一种动态类型的脚本语言&#xff0c;语法简洁明了&#xff0c;通常使用缩进来表示代码块。Java是一种静态类型的编程语言&#xff0c;语法更为严格&#xff0c;需要…...

QFlightInstruments飞行仪表控件库

QFlightInstruments 是一个开源的飞行仪表控件库&#xff0c;专为基于 Qt 的应用程序设计。它提供了一系列仿真实飞机仪表的组件&#xff0c;适用于飞行模拟软件、航空电子系统或任何需要高仿真飞行仪表显示的项目。 主要功能 高仿真飞行仪表&#xff1a;包括空速表、高度表、…...

可发1区的超级创新思路(python\matlab实现):MPTS+Lconv+注意力集成机制的Transformer时间序列模型

首先声明,该模型为原创!原创!原创!且该思路还未有成果发表,感兴趣的小伙伴可以借鉴! 应用场景 该模型主要用于时间序列数据预测问题,包含功率预测、电池寿命预测、电机故障检测等等。 一、模型整体架构(本文以光伏功率预测为例) 本模型由多尺度特征提取模块(MPTS)…...

Nginx — Nginx版本升级

例如&#xff1a;将10.224.11.220、10.224.11.221、10.208.11.220 三台服务器上的Nginx从1.21.1版本升级到1.23.3版本。 一、Nginx升级步骤 步骤一&#xff1a;备份老版本的Nginx&#xff08;10.224.11.220、10.224.11.221、10.208.11.220&#xff09; #关闭Nginx cd /usr/l…...

CSS学习笔记6——网页布局

目录 一、元素的浮动属性、清除浮动 清除浮动的其他方法 1、使用空标签清除浮动影响 2、使用overflow属性清除浮动 3、使用伪元素清除浮动影响 原理 overflow属性 二、元素的定位 1、相对定位 2、绝对定位 ​编辑 3、固定定位 z-index层叠等级属性 一、元素的浮动…...

C语言【指针二】

引言 介绍&#xff1a;const修饰指针&#xff0c;野指针 应用&#xff1a;指针的使用&#xff08;strlen的模拟实现&#xff09;&#xff0c;传值调用和传指调用 一、const修饰指针 1.const修饰变量 简单回顾一下前面学过的const修饰变量&#xff1a;在变量前面加上const&…...

第十六届蓝桥杯模拟二(串口通信)

由硬件框图可以知道我们要配置LED 和按键 一.LED 先配置LED的八个引脚为GPIO_OutPut,锁存器PD2也是,然后都设置为起始高电平,生成代码时还要去解决引脚冲突问题 二.按键 按键配置,由原理图按键所对引脚要GPIO_Input 生成代码,在文件夹中添加code文件夹,code中添加fun.…...

Java List 集合取交集、并集、差集、补集

在Java中&#xff0c;集合操作是编程中非常常见的需求&#xff0c;尤其是在处理数据集合时&#xff0c;如List、Set等。本文将详细介绍如何在Java中实现List集合的交集、并集、差集和补集操作&#xff0c;并提供代码示例和实现方法。 1. 交集操作 交集是指两个集合中都存在的元…...

SkyWalking+Springboot实战

1、下载SkyWalking APM 1.手动下载 Downloads | Apache SkyWalkinghttps://skywalking.apache.org/downloads/ 2.链接下载 https://dlcdn.apache.org/skywalking/10.2.0/apache-skywalking-apm-10.2.0.tar.gzhttps://dlcdn.apache.org/skywalking/10.2.0/apache-skywalking-…...

【小兔鲜】day01 项目、Vue3介绍、组合式API、小案例

【小兔鲜】day01 项目、Vue3介绍、组合式API、小案例 0. 市场上Vue前端工程师用到的技术1. Vue3小兔鲜先导课1.1 技术栈1.2 项目规模1.3 项目亮点1.4 课程安排 2. 认识Vue32.1 Vue3组合式API体验 3. create-vue创建Vue3项目3.1 新建项目结构3.2 小节3.3 补充说明npm init vuela…...

【Pandas DataFrame】

以下是 Pandas DataFrame 的核心知识点总结&#xff0c;用结构化分类帮你高效记忆关键操作和概念&#xff1a; 1. 基础操作 创建DataFrame 方法代码示例说明从字典创建df pd.DataFrame({A: [1,2], B: [3,4]})字典键为列名&#xff0c;值为数据从列表创建df pd.DataFrame([[…...

华为OD机试2025A卷 - 生成回文素数(Java Python JS C++ C )

最新华为OD机试 真题目录:点击查看目录 华为OD面试真题精选:点击立即查看 题目描述 求出大于或等于 N 的最小回文素数。 如果一个数大于 1,且其因数只有 1 和它自身,那么这个数是素数。 例如,2,3,5,7,11 以及 13 是素数。 如果一个数从左往右读与从右往左读是一…...

Jenkins教程(自动化部署)

Jenkins教程(自动化部署) 1. Jenkins是什么&#xff1f; Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具&#xff0c;广泛用于项目开发&#xff0c;具有自动化构建、测试和部署等功能。Jenkins用Java语言编写&#xff0c;可在Tomcat等流行的servlet容器中运行&…...

C#里使用libxl的对齐/边框/颜色

一份好的EXCEL文件,通道会有不同的颜色和边框来表示。 以便表示一些重要的信息,这样才能让人们一眼就看到需要关注的信息。 如下面所示: 要显示上面的内容,需要使用下面的例子: private void button12_Click(object sender, EventArgs e){var book = new ExcelBook();if…...

虚拟pinctrl驱动

之前呢&#xff0c;我们讲解了在内核中pinctrl子系统是怎么实现的&#xff0c;今天我们来尝试一下自己去写一个pinctrl子系统&#xff1a; 首先呢&#xff0c;我们来看看一个pinctrl子系统需要做的事情: 上面的话&#xff0c;我们看了一个pinctrl子系统需要的三大功能以及在驱…...

pycharm虚拟环境项目转移后配置解释器

添加解析器提示&#xff1a;无效的 Python SDK 解决方法 在到电脑安装python解析器&#xff0c;复制&#xff1a;python.exe和pythonw.exe 项目虚拟环境venv/Scripts Python解释器添加 项目现有虚拟环境&#xff0c;就可以正常使用...

蓝桥杯嵌入式学习笔记

用博客来记录一下参加蓝桥杯嵌入式第十六届省赛的学习经历 工具环境准备cubemx配置外部高速时钟使能设置串口时钟配置项目配置 keil配置烧录方式注意代码规范头文件配置 模块ledcubemx配置keil代码实现点亮一只灯实现具体操作的灯&#xff0c;以及点亮还是熄灭 按键cubemx配置k…...

0201-jsx语法基础-jsx-仿低代码平台项目

文章目录 1.jsx标签2.jsx属性3.jsx 事件3.1 声明事件3.2 使用事件&#xff08;对象&#xff09; 4. typescript类型基础4.1 类型声明4.2 事件函数传递自定义参数 5.插入js变量6. 条件判断7. 循环结语 1.jsx标签 jsx标签与html标签区别&#xff1a; 首字母大小写 大写是自定义组…...

在MCU工程中优化CPU工作效率的几种方法

在嵌入式系统开发中&#xff0c;优化 CPU 工作效率对于提升系统性能、降低功耗、提高实时性至关重要。Keil 作为主流的嵌入式开发工具&#xff0c;提供了多种优化策略&#xff0c;包括 关键字使用、内存管理、字节对齐、算法优化 等。本文将从多个方面介绍如何在 Keil 工程中优…...

Elasticsearch 的搜索功能

Elasticsearch 的搜索功能 建议阅读顺序&#xff1a; Elasticsearch 入门Elasticsearch 搜索&#xff08;本文&#xff09;Elasticsearch 搜索高级Elasticsearch 高级 1. 介绍 使用 Elasticsearch 最终目的是为了实现搜索功能&#xff0c;现在先将文档添加到索引中&#xff0c…...

【鸿蒙5.0】向用户申请麦克风授权

#效果图 步骤 在 config.json 里声明权限&#xff1a;在项目的 config.json 文件中添加麦克风权限的声明&#xff0c;告知系统应用需要使用该权限。检查权限状态&#xff1a;在代码里检查应用是否已经获得了麦克风权限。请求权限&#xff1a;若应用未获得麦克风权限&#xff0…...

数据结构与算法分析:树与哈希表(一)

遇到的问题&#xff0c;都有解决方案&#xff0c;希望我的博客能为你提供一点帮助。 一、概述 背景&#xff1a;链表处理大量数据时&#xff0c;线性访问耗时多。二叉查找树多数操作平均运行时间为 O (log N)&#xff0c;相对于链表树更加高效。 1.预备知识 1.1. 树的定义与…...

VBA第三十四期 VBA中怎么用OnKey事件

我们在VBA设计中经常需要使用到OnKey方法&#xff0c;特别是在窗口设计中比如我们想用到翻页按键&#xff0c;则就可以来建立一个OnKey事件。Setup_OnKey过程运行以后&#xff0c;就会达到最终效果&#xff0c;按PgDn键会将指针下移一行&#xff0c;按PgUp键会将指针上移一行。…...

HarmonyOS NEXT开发进阶(十五):日志打印 hilog 与 console.log 的区别

文章目录 一、前言二、两者区别对比三、HiLog 详解四、拓展阅读 一、前言 在日常开发阶段&#xff0c;日志打印是调试程序非常常用的操作&#xff0c;在鸿蒙的官方文档中介绍了hilog这种方式&#xff0c;前端转过来的开发者发现console.log也可以进行日志打印&#xff0c;而且…...

Skynet 框架中 gateserver、gate、watchdog 的关系

一、概述 在 Skynet 框架的网络通信架构中&#xff0c;gateserver、gate、watchdog 是三个核心组件&#xff0c;共同实现客户端连接的监听、管理和业务逻辑的分发。其设计目标是通过分层解耦&#xff0c;提升网络层的稳定性与业务逻辑的灵活性。 二、组件职责 1. ‌gateserve…...

第11章:优化I/O_《C++性能优化指南》_notes

第十一章核心知识点详解 11.1 读取文件的优化技巧 重点&#xff1a;减少内存分配、使用大缓冲区、优化函数调用链。 难点&#xff1a;理解系统调用开销与缓冲区大小的权衡。 代码示例与详解 示例1&#xff1a;使用高效函数签名和减少内存分配 #include <fstream> #inc…...

【C++初阶】--- 内存管理

1.C/C内存分布 我们一般说的32位机器和64位机器指的是虚拟空间的大小&#xff0c;也就是进程地址空间的大小&#xff0c;32位机器下&#xff0c;进程地址空间的大小是232个字节&#xff0c;也就是4G&#xff0c;64位机器下&#xff0c;进程地址空间的大小是264个字节,大概160亿…...

使用 Ansys Discovery 可视化液体池中的水流

了解 ANSYS Discovery&#xff1a;设计领域的变革者 ANSYS Discovery 是一款功能强大的软件工具&#xff0c;能够彻底改变设计流程。借助其先进的仿真功能&#xff0c;工程师现在可以在设计投入生产之前更深入地了解其设计。通过使用 ANSYS Discovery&#xff0c;设计师可以快…...