Spring Boot 自动配置
目录
什么是自动配置?
Spring 加载 Bean
@ComponentScan
@Import
导入类
导入 ImportSelector 接口的实现类
SpringBoot 原理分析
@EnableAutoConfiguration
@Import(AutoConfigurationImportSelector.class)
AutoConfigurationPackage
SpringBoot 自动配置流程
什么是自动配置?
Spring Boot 的自动配置:当 Spring 容器启动后,一些配置类、bean 对象等就自动存入 Ioc 容器中,而不再需要我们手动去声明,从而简化了程序开发过程,省去了繁琐的配置操作
也就是说,Spring Boot 的自动配置,就是 SpinrgBoot 将依赖 jar 包中的配置类以及 Bean 加载到 Spring Ioc 容器中的过程
在本篇文章中,我们主要学习一下两个方面:
1. Spring 如何将对象加载到 Spring Ioc 容器中
2. SpringBoot 是如何进行实现的
我们首先来看 Spring 是如何加载 Bean 的
Spring 加载 Bean
当我们在项目中引入第三方的包时,其实就是在该项目下引入第三方的代码,我们通过在该项目下创建不同的目录来模拟第三方代码的引入:
当前项目目录为 com.example.springautoconfig,模拟第三方代码文件在 com.example.autoconfig 目录下
第三方文件代码:
@Component
public class AutoConfig {public void test() {System.out.println("test...");}
}
获取 AutoConfig:
@SpringBootTest
class SpringAutoconfigApplicationTests {@Autowiredprivate ApplicationContext context;@Testvoid contextLoads() {AutoConfig bean = context.getBean(AutoConfig.class);System.out.println(bean);}
}
运行结果:
此时显示没有 com.example.autoconfig.AutoConfig 这个类型的 bean
为什么会报错呢?
Spring 使用 类注解(@Controller、@Service、@Repository、@Component、@Configuration) 和 @Bean 注解 帮助我们将 Bean 加载到 Spring Ioc 容器中时,有一个前提:这些注解需要和 SpringBoot 启动类(@SpringBootApplication 标注的类)在同一个目录下
而在上述项目中,启动类所在目录为 com.example.springautoconfig,而 AutoConfig 类位于 com.example.autoconfig 目录下,因此,SpringBoot 并没有扫描到
可是,当我们引入第三方的 jar 包时,第三方的 jar 代码目录也不在启动类的目录下,那么,如何让 Spring 帮我们管理这些 Bean 的呢?
我们可以通过指定路径或引入的文件告诉 Spring,让 Spring 进行扫描
常见的实现方法有两种:
1. @ComponentScan 组件扫描
2. @Import 导入
@ComponentScan
使用 @ComponentScan 注解,指定 Spring 扫描路径:
@SpringBootApplication
@ComponentScan("com.example.autoconfig")
public class SpringAutoconfigApplication {public static void main(String[] args) {SpringApplication.run(SpringAutoconfigApplication.class, args);}
}
运行程序并观察结果:
成功获取到 AutoConfig bean
那么,Spring Boot 是否使用了这种方式呢?
显然没有。若 Spring Boot 采用这种方式,当我们引入大量的第三方依赖,如 MyBatis、jackson 等时,就需要在启动类上配置不同依赖需要扫描的包,非常繁琐
@Import
@Import 导入主要有以下几种形式:
1. 导入类
2. 导入 ImportSelector 接口的实现类
导入类
@Import(AutoConfig.class)
@SpringBootApplication
public class SpringAutoconfigApplication {public static void main(String[] args) {SpringApplication.run(SpringAutoconfigApplication.class, args);}}
运行程序,观察结果:
成功获取到 AutoConfig Bean
若在文件中有多个配置项:
@Component
public class AutoConfig2 {public void test() {System.out.println("test...");}
}
此时就需要导入多个类:
@Import({AutoConfig.class, AutoConfig2.class})
@SpringBootApplication
public class SpringAutoconfigApplication {public static void main(String[] args) {SpringApplication.run(SpringAutoconfigApplication.class, args);}}
显而易见,这种方式也比较繁琐,因此,Spring Boot 也没有采用
导入 ImportSelector 接口的实现类
实现 ImportSelector 接口:
public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {// 返回需要导入的全限定类名return new String[]{"com.example.autoconfig.AutoConfig", "com.example.autoconfig.AutoConfig2"};}
}
导入:
@Import(MyImportSelector.class)
@SpringBootApplication
public class SpringAutoconfigApplication {public static void main(String[] args) {SpringApplication.run(SpringAutoconfigApplication.class, args);}}
运行程序,并观察结果:
这种方式也可以导入第三方依赖提供的 Bean
但是,它们都有一个明显的问题:使用者需要知道第三方依赖中有哪些 Bean 对象或配置类,若我们在导入过程中漏掉了一些 Bean,就可能会导致我们的项目出现问题
依赖中有哪些 Bean,使用时需要配置哪些 Bean,这些问题第三方依赖最为清楚,那么,能否由第三方依赖来做这些事情呢?
比较常见的方法是第三方依赖提供一个注解,而这个注解一般是以 @EnableXxx 开头的注解,而注解中封装的就是 @Import 注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
// 指定要导入哪些类
@Import(MyImportSelector.class)
public @interface EnableAutoConfig {
}
在启动类上使用第三方提供的注解:
@EnableAutoConfig
@SpringBootApplication
public class SpringAutoconfigApplication {public static void main(String[] args) {SpringApplication.run(SpringAutoconfigApplication.class, args);}}
运行并观察结果:
可以看到,这种方式也可以导入第三方依赖提供的 Bean,且这种方式不需要使用方知道第三方依赖中有哪些 Bean 对象或配置类,而在 Spring Boot 中也是使用的这种方式
SpringBoot 原理分析
SpringBoot 是如何进行实现的?让我们从 SpringBoot 的启动类开始看:
由 @SpringBootApplication 标注的类就是 SpringBoot 项目的启动类:
这个类与普通类的唯一区别就是 @SpringBootApplication 注解,这个注解也是 SpringBoot 实现自动配置的核心
@SpringBootApplication 是一个组合注解,注解中包含了:
1. 元注解:
JDK 中提供了 4 个 标准的用来对注解类型进行注解的注解类,称之为 meta-annotation(元注解)
分别为:
@Retention:描述注解保留的时间范围
@Target:描述注解的使用范围
@Documented:描述在使用 javadoc 工具为类生成帮助文档时是否保留其注解信息
@Inherited:使被其修饰的注解具有继承性(若某个类使用了 @Inherited,则其子类将自动具有该注解)
2. @SpringBootConfiguration:
标识当前类是一个配置类,里面其实就是 @Configuration,只是做了进一步的封装
其中,@Indexed 注解是用来加速应用启动的
3. @EnableAutoConfiguration(开启自动配置)
是 spiring 自动配置的核心注解,我们在后续详细理解
4. ComponentScan(包扫描)
可以通过 basePackageClasses 或 basePackages 来定义要扫描的特定包,若没有定义特定的包,将从声明该注解的类的包开始扫描,这也是 SpringBoot 项目声明的注解类为什么必须在启动类目录下
也可以自定义过滤器,用于排查一些类、注解等
接下来,我们重点来看 @EnableAutoConfiguration(开启自动配置)
@EnableAutoConfiguration
@EnableAutoConfiguration 中主要包含两部分:
@Import(AutoConfigurationImportSelector.class)
@AutoConfigurationPackage
我们先来看 @Import(AutoConfigurationImportSelector.class)
@Import(AutoConfigurationImportSelector.class)
使用 @Import 注解,导入了实现 ImportSelector 接口的实现类:
在 selectImports() 方法中,调用了 getAutoConfigurationEntry() 方法,获取可自动配置的配置类信息
我们继续看 getAutoConfigurationEntry() 方法:
在 getAutoConfigurationEntry() 方法中,主要通过 getCandidateConfigurations(annotationMetadata, attributes) 方法 和 fireAutoConfigurationImportEvents(configurations, exclusions) 方法,获取在配置文件中配置的所有自动配置类的集合
我们先看 getCandidateConfigurations(annotationMetadata, attributes) 方法:
在 getCandidateConfigurations(annotationMetadata, attributes) 方法中,使用 ImportCandidates 进行加载
那么,从哪里进行加载呢?
从 断言 的错误信息中我们可以找到答案:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
也就是说, getCandidateConfigurations 方法会获取所有基于META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中配置类的集合
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件:
其中包含了很多第三方依赖的配置文件
我们以 redis 为例:
查看 RedisAutoConfiguration:
可以看到,在使用 redis 时常用的 RedisTemplate 和 StringRedisTemplate 就位于其中,在我们需要使用时直接使用 @Autowired 进行注入就可以了
但是,由于当前项目并没有引入 redis 相关 jar 包,此时这个类并不能被加载
也就是说在加载自动配置类的时候,并不是将所有的配置全部加载进来,而是会先进行判断,根据 @ConditionalOnMissingBean 、@ConditionalOnSingleCandidate 等注解的判断进行动态加载
即,在配置文件中使用 @Bean 声明对象,spring 会自动调用配置类中使用 @Bean 标识的方法,并将对象存放到 Spring Ioc 中,但是,在加载自动配置类的时候,并不是将所有的配置全部加载进来,而是会通过 @Conditional 等注解的判断进行动态加载(@Conditional 是 spring 底层注解,会根据不同的条件,进行条件判断,若满足指定条件,配置类中的配置才会生效)
我们继续看 fireAutoConfigurationImportEvents 方法,找到是从哪里获取配置类的:
可以看到,fireAutoConfigurationImportEvents 方法最终会从 META-INF/spring.factories 中获取配置类的集合
我们来看 META-INF/spring.factories:
META-INF/spring.factories 文件是 Spring 内部提供的一个约定俗称的加载方式,只需要在模块的 META-INF/spring.factories 文件中进行配置,Spring 就会把相应的实现类注入到 Spring 容器中
例如,有一个自动配置类,希望 SpringBoot 在启动时自动加载这个配置,我们就可以在 META-INF/spring.factories 文件按照指定格式进行配置,让 Spring Boot 应用启动时,读取这个 spring.factories 文件,根据文件中指定的配置类来进行自动配置
spring 会加载所有 jar 包下的 META-INF/spring.factories 文件
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 和 META-INF/spring.factories 都在引入的起步依赖中:
我们继续看 AutoConfigurationPackage
AutoConfigurationPackage
在这个注解中,主要导入了一个配置文件 AutoConfigurationPackages.Registrar.class
我们继续看 Registrar :
Registrar 实现了 ImportBeanDefinitionRegistrar 接口,可以被 @Import 导入到 spring 容器中
new PackageImports(metadata).getPackageNames().toArray(new String[0]): 当前启动类所在的包名
也就是说,@AutoConfigurationPackage 的作用是 将启动类所在的包下面所有的组件都扫描注册到 spring 容器中
最后,我们来总结一下 SpringBoot 自动配置的流程
SpringBoot 自动配置流程
SpringBoot 的自动配置的入口是 @SpringBootApplication 注解,在这个注解中,主要封装了 3 个注解:
@SpringBootConfiguration:标识当前类是配置类
@ComponentScan(包扫描):可以通过 basePackageClasses 或 basePackages 定义要扫描的特定包,若没有定义特定的包,将从声明该注解的类的包开始扫描,也就是说,默认情况下扫描的是启动类所在的当前包以及子包
@EnableAutoConfiguration(开启自动配置):主要包含两部分:
@Import(AutoConfigurationImportSelector.class) :读取 META-INF/spring.factories 和 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中定义的配置类
@AutoConfigurationPackage:将启动类所在的包下所有组件都注入到 Spring 容器中
相关文章:
Spring Boot 自动配置
目录 什么是自动配置? Spring 加载 Bean ComponentScan Import 导入类 导入 ImportSelector 接口的实现类 SpringBoot 原理分析 EnableAutoConfiguration Import(AutoConfigurationImportSelector.class) AutoConfigurationPackage SpringBoot 自动配置流…...
PyQt6医疗多模态大语言模型(MLLM)实用系统框架构建初探(下.代码部分)
医疗 MLLM 框架编程实现 本医疗 MLLM 框架结合 Python 与 PyQt6 构建,旨在实现多模态医疗数据融合分析并提供可视化界面。下面从数据预处理、模型构建与训练、可视化界面开发、模型 - 界面通信与部署这几个关键部分详细介绍编程实现。 6.1 数据预处理 在医疗 MLLM 框架中,多…...
【LC】1148. 文章浏览 I
题目描述: Views 表: ------------------------ | Column Name | Type | ------------------------ | article_id | int | | author_id | int | | viewer_id | int | | view_date | date | ----------------------…...
Linux学习笔记——网络管理命令
一、网络基础知识 TCP/IP四层模型 以太网地址(MAC地址): 段16进制数据 IP地址: 子网掩码: 二、接口管命令 ip命令:字符终端,立即生效,重启配置会丢失 nmcli命令:字符…...
Arduino大师练成手册 --控制 OLED
要在 Arduino 上使用 U8glib 库控制带有 7 个引脚的 SPI OLED 显示屏,你可以按照以下步骤进行: 7pin OLED硬件连接 GND:连接到 Arduino 的 GND 引脚。 VCC:连接到 Arduino 的 5V 引脚。 D0(或 SCK/CLK)…...
2024年终总结
距离放假还有一个小时,闲来无事,写篇总结。 最近关注我的朋友不少,关注我的多半都是因为几篇博客。既然关注了,我也想分享点工作中的经验给大家。 今年的节点是跳槽。 4月份跳槽的,跳槽之前呢在上家公司还有3W多奖金…...
Kafka 消费端反复 Rebalance: `Attempt to heartbeat failed since group is rebalancing`
文章目录 Kafka 消费端反复 Rebalance: Attempt to heartbeat failed since group is rebalancing1. Rebalance 过程概述2. 错误原因分析2.1 消费者组频繁加入或退出2.1.1 消费者故障导致频繁重启2.1.2. 消费者加入和退出导致的 Rebalance2.1.3 消费者心跳超时导致的 Rebalance…...
【Linux】Linux编译器-g++、gcc、动静态库
只要积极创造,机遇无时不有;只要善于探索,真理无处不在。💓💓💓 目录 ✨说在前面 🍋知识点一:Linux编译器-g、gcc •🌰1. 背景知识 •🌰2. gcc如何完成 •…...
android12源码中用第三方APK替换原生launcher
一、前言 如何用第三方的apk替换原生launcher呢?我是参考着这位大神的博客https://blog.csdn.net/hyu001/article/details/131044358做的,完美实现。 这边博客中又加入了我个人的一些改变,整理的。 二、步骤 1.在/packages/apps/MyApp文件…...
Ubuntu20.04 深度学习环境配置(持续完善)
文章目录 常用的一些命令安装 Anaconda创建conda虚拟环境查看虚拟环境大小 安装显卡驱动安装CUDA安装cuDNN官方仓库安装 cuDNN安装 cuDNN 库验证 cuDNN 安装确认 CUDA 和 cuDNN 是否匹配: TensorRT下载 TensorRT安装 TensorRT 本地仓库配置 GPG 签名密钥安装 Tensor…...
Java 实现Excel转HTML、或HTML转Excel
Excel是一种电子表格格式,广泛用于数据处理和分析,而HTM则是一种用于创建网页的标记语言。虽然两者在用途上存在差异,但有时我们需要将数据从一种格式转换为另一种格式,以便更好地利用和展示数据。本文将介绍如何通过 Java 实现 E…...
jQuery小游戏
jQuery小游戏(一) 嘻嘻,今天我们来写个jquery小游戏吧 首先,我们准备一下写小游戏需要准备的佩饰,如果:图片、音乐、搞怪的小表情 这里我准备了一些游戏中需要涉及到的图片 游戏中使用到的方法 eval() 函…...
Cpp::静态 动态的类型转换全解析(36)
文章目录 前言一、C语言中的类型转换二、为什么C会有四种类型转换?内置类型 -> 自定义类型自定义类型 -> 内置类型自定义类型 -> 自定义类型隐式类型转换的坑 三、C强制类型转换static_castreinterpret_castconst_castdynamic_cast 四、RTTI总结 前言 Hell…...
【PostgreSQL内核学习 —— (WindowAgg(一))】
WindowAgg 窗口函数介绍WindowAgg理论层面源码层面WindowObjectData 结构体WindowStatePerFuncData 结构体WindowStatePerAggData 结构体eval_windowaggregates 函数update_frameheadpos 函数 声明:本文的部分内容参考了他人的文章。在编写过程中,我们尊…...
SQL-leetcode—1158. 市场分析 I
1158. 市场分析 I 表: Users ----------------------- | Column Name | Type | ----------------------- | user_id | int | | join_date | date | | favorite_brand | varchar | ----------------------- user_id 是此表主键(具有唯一值的列ÿ…...
opensips中各个模块的解释
模块名称作用说明aaa_diameter提供基于 Diameter 协议的认证、授权和计费服务,适用于移动运营商和ISP的计费系统。aaa_radius提供基于 RADIUS 协议的认证、授权和计费功能,常用于无线网络接入和VPN等场景。auth_jwt用于支持基于 JSON Web Token (JWT) 的…...
【C++初阶】第11课—vector
文章目录 1. 认识vector2. vector的遍历3. vector的构造4. vector常用的接口5. vector的容量6. vector的元素访问7. vector的修改8. vector<vector\<int\>>的使用9. vector的使用10. 模拟实现vector11. 迭代器失效11.1 insert插入数据内部迭代器失效11.2 insert插入…...
SpringBoot开发(二)Spring Boot项目构建、Bootstrap基础知识
1. Spring Boot项目构建 1.1. 简介 基于官方网站https://start.spring.io进行项目的创建. 1.1.1. 简介 Spring Boot是基于Spring4框架开发的全新框架,设计目的是简化搭建及开发过程,并不是对Spring功能上的增强,而是提供了一种快速使用Spr…...
vim如何设置自动缩进
:set autoindent 设置自动缩进 :set noautoindent 取消自动缩进 (vim如何使设置自动缩进永久生效:vim如何使相关设置永久生效-CSDN博客)...
Jenkins上生成的allure report打不开怎么处理
目录 问题背景: 原因: 解决方案: Jenkins上修改配置 通过Groovy脚本在Script Console中设置和修改系统属性 步骤 验证是否清空成功 进一步的定制 也可以使用Nginx去解决 使用逆向代理服务器Nginx: 通过合理调整CSP配置&a…...
ASP.NET Blazor托管模型有哪些?
今天我们来说说Blazor的三种部署方式,如果大家还不了解Blazor,那么我先简单介绍下Blazor Blazor 是一种 .NET 前端 Web 框架,在单个编程模型中同时支持服务器端呈现和客户端交互性: ● 使用 C# 创建丰富的交互式 UI。 ● 共享使用…...
使用 Confluent Cloud 的 Elasticsearch Connector 部署 Elastic Agent
作者:来自 Elastic Nima Rezainia Confluent Cloud 用户现在可以使用更新后的 Elasticsearch Sink Connector 与 Elastic Agent 和 Elastic Integrations 来实现完全托管且高度可扩展的数据提取架构。 Elastic 和 Confluent 是关键的技术合作伙伴,我们很…...
二叉树的最小深度力扣--111
目录 题目 思路 代码 题目 给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明:叶子节点是指没有子节点的节点。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出࿱…...
PySide(PyQT)进行SQLite数据库编辑和前端展示的基本操作
以SQLite数据库为例,学习数据库的基本操作,使用QSql模块查询、编辑数据并在前端展示。 SQLite数据库的基础知识: https://blog.csdn.net/xulibo5828/category_12785993.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId1278…...
ARM64平台Flutter环境搭建
ARM64平台Flutter环境搭建 Flutter简介问题背景搭建步骤1. 安装ARM64 Android Studio2. 安装Oracle的JDK3. 安装 Dart和 Flutter 开发插件4. 安装 Android SDK5. 安装 Flutter SDK6. 同意 Android 条款7. 运行 Flutter 示例项目8. 修正 aapt2 报错9. 修正 CMake 报错10. 修正 N…...
Linux系统编程:进程状态和进程优先级/nice
目录 一,相对于OS的进程状态 1.1运行状态 1.2阻塞状态 1.3挂起状态 二,并发执行与进程切换 2.1,CPU并发执行 2.2进程切换 三,Linux内核管理进程状态的方法 3.1查看进程状态 3.2R状态 3.3S状态 3.4D状态 3.5T状态 3.6X状态 3.7Z状态 3.8孤儿进程 四,进程优先级 …...
【算法】数论基础——唯一分解定理(算术基本定理)python
目录 定义进入正题热身训练实战演练总结 定义 唯一分解定理:也叫做算数基本定理: 任意一个大于1的整数N,都可以唯一分解为若干个质数的乘积 换句话说,任何大于1的整数n可以表示为: 例如: 30 2^1 * 3^1 * 5^1 100 2^2…...
图形化数据报文转换映射工具
目录 概要整体架构流程技术名词解释技术细节小结 概要 在当今数字化时代,数据的处理和分析是企业、科研机构以及各类组织日常运营的核心环节。数据来源广泛,格式多样,常见的数据格式包括XML(可扩展标记语言)和JSON&a…...
性能优化案例:通过合理设置spark.shuffle.memoryFraction参数的值来优化PySpark程序的性能
在PySpark中,合理调整spark.shuffle.memoryFraction参数可以有效优化Shuffle阶段的性能,尤其是在存在大量磁盘溢出的场景下。 通过合理设置spark.shuffle.memoryFraction并结合其他优化手段,可显著减少Shuffle阶段的磁盘I/O,提升P…...
[C]基础9.深入理解指针(1)
博客主页:算法歌者本篇专栏:[C]您的支持,是我的创作动力。 文章目录 0、总结1、内存和地址1.1 内存1.2 理解编址 2、指针变量和地址2.1 取地址操作符(&)2.2 指针变量2.3 解引用操作符(*)2.4…...
网络模型简介:OSI七层模型与TCP/IP模型
计算机网络是现代信息社会的基石,而网络通信的基础在于理解网络模型。网络模型是对通信过程的抽象,它帮助我们理解数据从源到目的地的传输过程。常见的网络模型有 OSI 七层模型 和 TCP/IP 模型,这两种模型在理论和实践中都起着重要作用。 一、…...
第100+35步 ChatGPT学习:时间序列EMD-ARIMA-RF模型 vol. 2
基于Python 3.9版本演示 一、写在前面 上一节,我们学了EMD-ARIMA-RF模型去做预测。 这一节开始,我们尝试使用多项式回归矫正。 二、EMD&RF-ARIMA组合策略 该组合策略主要是将传统的经验模态分解(EMD)方法和现代的机器学习技…...
Adobe的AI生成3D数字人框架:从自拍到生动的3D化身
一、引言 随着人工智能技术的发展,我们见证了越来越多创新工具的出现,这些工具使得图像处理和视频编辑变得更加智能与高效。Adobe作为全球领先的创意软件公司,最近推出了一项令人瞩目的新技术——一个能够将普通的二维自拍照转换成栩栩如生的三维(3D)数字人的框架。这项技…...
2025美赛数学建模MCM/ICM选题建议与分析,思路+模型+代码
2025美赛数学建模MCM/ICM选题建议与分析,思路模型代码,详细更新见文末名片 一、问题A:测试时间:楼梯的恒定磨损(Archaeological Modeling) 适合专业:考古学、历史学、数学、机械工程 难度:中等…...
golang中的包管理-上--简介
Go语言中的包(Package)是组织和管理代码的基本单元,通过合理地使用包,可以提高代码的复用性、可维护性和可读性。 包的基本概念和定义 在Go语言中,每个源代码文件都属于一个包。包的声明位于文件的最顶部ÿ…...
深入了解 HTTP 头部中的 Accept-Encoding:gzip、deflate、br、zstd
在现代Web开发中,性能优化是至关重要的一部分。HTTP协议中的Accept-Encoding头部正是为性能提升提供了一个非常有效的方式,它告知服务器客户端能够理解并接收哪些压缩算法的响应内容。在这篇博客中,我们将详细探讨Accept-Encoding头部的作用&…...
QModbusTCPClient 服务器断开引起的程序崩溃
最近使用QModbusTCPClient 与一套设备通信,有一个QTimer频繁的通过读取设备寄存器。程序运行良好,但是有个问题:正常进行中设备断电了,整个程序都会崩溃。解决过程如下: 1.失败方案一 在QModbusTCPClient的errorOccu…...
Unity|小游戏复刻|见缝插针2(C#)
控制针的运动 新建一个Pin脚本 将Pin脚本拖到针Pin的下面 保存代码 using UnityEngine;public class Pin : MonoBehaviour {public float speed 5;private bool isFly false;private bool isReach false;private Transform startPosition;// Start is called once bef…...
数据结构——堆(C语言)
基本概念: 1、完全二叉树:若二叉树的深度为h,则除第h层外,其他层的结点全部达到最大值,且第h层的所有结点都集中在左子树。 2、满二叉树:满二叉树是一种特殊的的完全二叉树,所有层的结点都是最…...
ML基础2-python中的可视化1:matplotlib
承接我的上一篇博客: https://blog.csdn.net/weixin_62528784/article/details/145329298?spm1001.2014.3001.5501 在机器学习的过程中,我们需要掌握大量的Python包,常用的有pandas和numpy这些基本数据管理的包(在后续更新中我会讲解)与mat…...
SpringBoot--基本使用(配置、整合SpringMVC、Druid、Mybatis、基础特性)
这里写目录标题 一.介绍1.为什么依赖不需要写版本?2.启动器(Starter)是何方神圣?3.SpringBootApplication注解的功效?4.启动源码5.如何学好SpringBoot 二.SpringBoot3配置文件2.1属性配置文件使用2.2 YAML配置文件使用2.3 YAML配置文件使用2.…...
9.C++文件与流
C文件与流 在 C 中,文件和流是用于处理输入输出操作的重要概念,以下是关于它们的详细讲解: 流的概念 定义:流是一种抽象概念,它代表了数据的序列。在 C 中,流可以是输入流(从外部源如文件或键…...
CSRF 跨站请求伪造漏洞
原理 当一个网站A使用Cookie,存储Session或Token来用于单点登录和权限操作时。浏览器将Cookie存储到浏览器中。当用户在访问另一个网站V时,黑客可以通过伪造表单,向网站A发送修改重要信息(如密码)、支付等操作,浏览器会自动携带C…...
从ABCD谈人工智能对软件开发的影响(2)
接“造词圈子割韭菜”-从ABCD谈人工智能对软件开发的影响(1) (六)分步解析之二:组织价值(业务用例图) 这一步本来建模难度也只有,AI的助力分数可以做到30分。 ★很多领域驱动设计…...
我谈《概率论与数理统计》的知识体系
学习《概率论与数理统计》二十多年后,在廖老师的指导下,才厘清了各章之间的关系。首先,这是两个学科综合的一门课程,这一门课程中还有术语冲突的问题。这一门课程一条线两个分支,脉络很清晰。 概率论与统计学 概率论…...
第 10 课 Python 内置函数
1. 什么是内置函数 Python解释器也是一个程序,它给用户提供了一些常用功能,并给它们起了独一无二的名字,这些常用功能就是内置函数。Python解释器启动以后,内置函数也生效了,可以直接拿来使用。 内置函数是解释器的一部分,它随着解释器的启动而生效;标准库函数是…...
MySQL中的读锁与写锁:概念与作用深度剖析
MySQL中的读锁与写锁:概念与作用深度剖析 在MySQL数据库的并发控制机制中,读锁和写锁起着至关重要的作用。它们是确保数据在多用户环境下能够正确、安全地被访问和修改的关键工具。 一、读锁(共享锁)概念 读锁,也称为…...
Kotlin Bytedeco OpenCV 图像图像50 仿射变换 图像缩放
Kotlin Bytedeco OpenCV 图像图像50 仿射变换 图像缩放 1 添加依赖2 测试代码3 测试结果 在OpenCV中,仿射变换(Affine Transformation)和透视变换(Perspective Transformation)是两种常用的图像几何变换方法。 变换方…...
导出地图为图像文件
使用函数可以将地图或布局视图的内容导出为图像文件. 操作方法: 1.打开目标地图文档 2.导入arcpy.mapping模块 import arcpy.mapping as mapping 3.引用当前活动地图文档,把该引用赋值给变量 mxd mapping.MapDocument() 4.获取地图文档中的数据框列表,查找目标数据框,并…...
【Linux】命令为桥,存在为岸,穿越虚拟世界的哲学之道
文章目录 Linux基础入门:探索操作系统的内核与命令一、Linux背景与发展历史1.1 Linux的起源与发展1.2 Linux与Windows的对比 二、Linux的常用命令2.1 ls命令 - "List"(列出文件)2.2 pwd命令 - "Print Working Directory"(…...