【Spring Boot 源码学习】深入 FilteringSpringBootCondition
走近 AutoConfigurationImportFilter
- 引言
- 往期内容
- 主要内容
- 1. match 方法
- 2. ClassNameFilter 枚举类
- 3. filter 方法
- 总结
引言
前两篇博文笔者带大家从源码深入了解了 Spring Boot 的自动装配流程,其中自动配置过滤的实现由于篇幅限制,还未深入分析。
那么从本篇开始,Huazie 就带大家走近 AutoConfigurationImportFilter
,一起从源码解析 FilteringSpringBootCondition
、OnBeanCondition
、OnClassCondition
、OnWebApplicationCondition
的实现。
往期内容
在开始本篇的内容介绍之前,我们先来看看往期的系列文章【有需要的朋友,欢迎关注系列专栏】:
Spring Boot 源码学习 |
Spring Boot 项目介绍 |
Spring Boot 核心运行原理介绍 |
【Spring Boot 源码学习】@EnableAutoConfiguration 注解 |
【Spring Boot 源码学习】@SpringBootApplication 注解 |
【Spring Boot 源码学习】走近 AutoConfigurationImportSelector |
【Spring Boot 源码学习】自动装配流程源码解析(上) |
【Spring Boot 源码学习】自动装配流程源码解析(下) |
主要内容
在开始本篇内容之前,我们再次来回顾一下上篇博文介绍的 AutoConfigurationImportFilter
的源码和相关的类图:
@FunctionalInterface
public interface AutoConfigurationImportFilter {// 自动配置组件的过滤匹配boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata);
}
通过上面的关联类图,我们可以看到 AutoConfigurationImportFilter
接口实际上是由抽象类 FilteringSpringBootCondition
来实现的,另外翻看它的源码,该抽象类还定义了一个抽象方法 getOutcomes
,然后 OnBeanCondition
、OnClassCondition
、OnWebApplicationCondition
继承该抽象类,实现 getOutcomes
方法,完成实际的过滤匹配操作。
本篇,我们就从源码入手重点介绍 FilteringSpringBootCondition
:
1. match 方法
上一篇博文我们已经从 FilteringSpringBootCondition
的部分源码进行了分析,它的 match
方法主要是调用 getOutcomes
方法,并将其返回的结果转换成布尔数组。而这个 getOutcomes
方法是过滤匹配的核心功能,由抽象类 FilteringSpringBootCondition 的子类来实现它。
这里再简单回顾一下 match
方法的处理逻辑:
@Override
public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) {ConditionEvaluationReport report = ConditionEvaluationReport.find(this.beanFactory);// 调用 由子类实现的 getOutcomes 方法,完成实际的过滤匹配操作ConditionOutcome[] outcomes = getOutcomes(autoConfigurationClasses, autoConfigurationMetadata);boolean[] match = new boolean[outcomes.length];// 将 getOutcomes 方法返回结果转换成布尔数组for (int i = 0; i < outcomes.length; i++) {match[i] = (outcomes[i] == null || outcomes[i].isMatch());if (!match[i] && outcomes[i] != null) {logOutcome(autoConfigurationClasses[i], outcomes[i]);if (report != null) {report.recordConditionEvaluation(autoConfigurationClasses[i], this, outcomes[i]);}}}return match;
}
上述代码中,我们可以看到,将 getOutcomes
方法返回结果转换成布尔数组的循环逻辑中有一段代码如下:
match[i] = (outcomes[i] == null || outcomes[i].isMatch());
这里是将返回结果转换成布尔值,分别是:
- 如果匹配结果为
null
,认为符合匹配要求, 设置match[i] = true
; - 如果匹配结果不为
null
,并且 匹配对象的isMatch = true
,也认为符合匹配要求, 设置match[i] = true
;
这个时候,我们就能理解 上篇博文讲到的 不符合过滤匹配要求,则清空当前的自动配置组件 的逻辑:
当然 FilteringSpringBootCondition
内还有其他的内容,这些内容在它的子类中也将使用到,我们先提前了解下,以便后续能更好地理解子类的功能实现。
2. ClassNameFilter 枚举类
首先查看 ClassNameFilter
枚举类的源码【Spring Boot 2.7.9】:
protected enum ClassNameFilter {PRESENT {@Overridepublic boolean matches(String className, ClassLoader classLoader) {return isPresent(className, classLoader);}},MISSING {@Overridepublic boolean matches(String className, ClassLoader classLoader) {return !isPresent(className, classLoader);}};abstract boolean matches(String className, ClassLoader classLoader);// ....}
ClassNameFilter
枚举类包含两个枚举常量,分别是 PRESENT
和 MISSING
;这两个枚举常量都实现了 ClassNameFilter
枚举类定义的 matches
的抽象方法,其中
PRESENT
中的matches
返回isPresent(className, classLoader);
MISSING
中的matches
返回!isPresent(className, classLoader);
我们继续看 isPresent 方法,分析一下它的功能:
static boolean isPresent(String className, ClassLoader classLoader) {if (classLoader == null) {classLoader = ClassUtils.getDefaultClassLoader();}try {resolve(className, classLoader);return true;}catch (Throwable ex) {return false;}
}protected static Class<?> resolve(String className, ClassLoader classLoader) throws ClassNotFoundException {if (classLoader != null) {return Class.forName(className, false, classLoader);}return Class.forName(className);
}
上述 isPresent
方法的逻辑其实也并不复杂,就是通过类加载器去加载指定的类【即 className 字符串对应的类】:
- 如果指定的类加载成功,则直接返回
true
; - 如果指定的类加载失败,则要抛出异常,捕获异常后,返回
false
。
那显然 ClassNameFilter.PRESENT.matches(className, classLoader)
用于校验指定的类是否加载成功:
- 如果指定的类加载成功,则返回
true
; - 如果指定的类加载失败,则返回
false
。
而 ClassNameFilter.MISSING.matches(className, classLoader)
用于校验指定的类是否加载失败:
- 如果指定的类加载失败,则返回
true
; - 如果指定的类加载成功,则返回
false
。
3. filter 方法
继续翻看 FilteringSpringBootCondition
源码,还有一个 filter
方法需要重点介绍下:
protected final List<String> filter(Collection<String> classNames, ClassNameFilter classNameFilter, ClassLoader classLoader) {if (CollectionUtils.isEmpty(classNames)) {return Collections.emptyList();}List<String> matches = new ArrayList<>(classNames.size());for (String candidate : classNames) {if (classNameFilter.matches(candidate, classLoader)) {matches.add(candidate);-}}return matches;
}
结合上面的 ClassNameFilter
枚举类,我们可以很容易理解上面的代码逻辑。
- 如果
classNameFilter
是ClassNameFilter.PRESENT
,则filter
方法获取指定的类集合中加载成功的类集合【即匹配成功的类集合】; - 如果
classNameFilter
是ClassNameFilter.MISSING
,则filter
方法获取指定的类集合中加载失败的类集合【即匹配失败的类集合】。
总结
本篇 Huazie 带大家介绍了自动配置过滤匹配的核心父类 FilteringSpringBootCondition
,这对于笔者后续博文详解它的三个子类【OnBeanCondition
、OnClassCondition
、OnWebApplicationCondition
】非常重要,敬请期待!!!。
相关文章:

【Spring Boot 源码学习】深入 FilteringSpringBootCondition
走近 AutoConfigurationImportFilter 引言往期内容主要内容1. match 方法2. ClassNameFilter 枚举类3. filter 方法 总结 引言 前两篇博文笔者带大家从源码深入了解了 Spring Boot 的自动装配流程,其中自动配置过滤的实现由于篇幅限制,还未深入分析。 …...

docker 笔记6:高级篇 DockerFile解析
目录 1.是什么? 2.构建三步骤 3.DockerFile构建过程解析 3.1 Dockerfile内容基础知识 3.2Docker执行Dockerfile的大致流程 总结 4.DockerFile常用保留字指令 5.案例:自定义镜像 5.1 要求: Centos7镜像具备vimifconfigjdk8 5.2编写 5…...

微信小程序navigateTo进入页面后返回原来的页面需要携带数据回来
需求 如图:点击评论后会通过wx.navigateTo进入到评论页面,评论完返回count给原页面,重新赋值实现数量动态变化,不然要刷新这个页面才会更新最新的评论数量。 实现方式: 在评论页面通过wx.setStorageSync(‘data’…...

Python照片压缩教程详解
介绍 在日常的编程工作中,我们经常需要处理图像,例如上传、下载、显示、编辑等。有时候,我们需要对图像进行压缩,以减少占用的空间和带宽,提高加载速度和用户体验。那么,如何用Python来实现图像压缩呢&…...

软路由的负载均衡设置:优化网络性能和带宽利用率
在现代网络环境中,提升网络性能和最大化带宽利用率至关重要。通过合理配置软路由IP的负载均衡设置,可以有效地实现这一目标,并提高整体稳定性与效果。本文将详细介绍如何进行软路由IP的负载均衡设置,从而优化网络表现、增加带宽利…...

CH06_第一组重构(上)
提取函数(Extract Function |106) 曾用名:提炼函数(Extract Function) 反向重构:内联函数(115) 示例代码 function printOwing(invoice) {printBanner();let outstanding calcul…...

RHCSA-VMware Workstation Pro-Linux基础配置命令
1.代码命令 1.查看本机IP地址: ip addr 或者 ip a [foxbogon ~]$ ip addre [foxbogon ~]$ ip a 1:<Loopback,U,LOWER-UP> 为环回2网卡 2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP>为虚拟机自身网卡 2.测试网络联通性: [f…...
YOLO-NAS详细教程-姿势估计实现
姿势估计是一项计算机视觉任务,涉及估计图像或视频中物体或人的位置和方向。它通常涉及识别特定的关键点或身体部位(例如关节),并确定它们的相对位置和方向。姿势估计有许多应用,包括机器人、增强现实、人机交互和运动分析。 自上而下和自下而上是姿态估计中两种常用的方法…...

【扩散模型 李宏毅B站教学以及基础代码运用】
李宏毅教学视频: Link1 B站DDPM公式推导以及代码实现: Link2 这个视频里面有论文里面的公式推导,并且1小时10分开始讲解实例代码。 文章目录 扩散模型概念:Diffusion Model工作原理:影像生成模型本质上的共同目标B站…...

SpringBoot隐藏文件
1.设置 2.输入file Types 3.点击忽略文件或者文件夹 4.成功...
常见数据库介绍对比之SQL关系型数据库
1.关系型数据库介绍 关系型数据库是一种基于关系模型的数据库,它使用表格来组织和存储数据。下面是一些常见的关系型数据库: 1.1. MySQL MySQL是一种开源的关系型数据库管理系统(RDBMS),广泛用于Web应用程序和企业级…...

OLED透明屏模块:引领未来显示技术的突破
OLED透明屏模块作为一项引领未来显示技术的突破,以其独特的特点和卓越的画质在市场上引起了广泛关注。 根据行业报告,预计到2025年,OLED透明屏模块将占据智能手机市场的20%份额,并在汽车导航系统市场中占据30%以上份额。 那么&am…...
Python_操作记录
1、Pandas读取数据文件(以文本文件作为示例),sep表示间隔,headerNone表示无标题行 df pd.read_table("data/youcans3.dat", sep"\t", headerNone) 2、线性规划问题求解 1)问题定义,…...

常用激活函数整理
最近一边应付工作,一边在补足人工智能的一些基础知识,这个方向虽然新兴,但已是卷帙浩繁,有时不知从何入手,幸亏有个适合基础薄弱的人士学习的网站,每天学习一点,积跬步以至千里吧。有像我一样学…...
uniapp 地图跳转到第三方导航软件 直接打包成apk
// 判断是否存在导航软件judgeHasExistNavignation() {let navAppParam [{pname: com.baidu.BaiduMap,action: baidumap://}, // 百度{pname: com.autonavi.minimap,action: iosamap://}, // 高德{pname: com.tencent.map,action: tencentmap://}, // 腾讯];return navAppPara…...

CentOS 8 通过YUM方式升级最新内核
CentOS 8 通过YUM方式升级最新内核 查看当前内核 uname -r 4.18.0-193.6.3.el8_2.x86_64导入 ELRepo 仓库的公钥: rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org安装升级内核相关的yum源仓库(安装 ELRepo 仓库的 yum 源) yum install https://www…...

java 版本企业招标投标管理系统源码+功能描述+tbms+及时准确+全程电子化
功能描述 1、门户管理:所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含:招标公告、非招标公告、系统通知、政策法规。 2、立项管理:企业用户可对需要采购的项目进行立项申请,并提交审批,查看所…...

Python爬虫数据存哪里|数据存储到文件的几种方式
前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 爬虫请求解析后的数据,需要保存下来,才能进行下一步的处理,一般保存数据的方式有如下几种: 文件:txt、csv、excel、json等,保存数据量小。 关系型数据库…...

软件测试/测试开发丨Web自动化 测试用例流程设计
点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接:https://ceshiren.com/t/topic/27173 一、测试用例通用结构回顾 1.1、现有测试用例存在的问题 可维护性差可读性差稳定性差 1.2、用例结构设计 测试用例的编排测试用例的项目结构 1…...
git撤销修改命令
要撤销Git中尚未提交的所有修改,可以使用以下几种方法: 1、使用git checkout命令丢弃工作目录的修改,重置工作目录中所有文件的修改。 git checkout . 2、使用git reset命令重置暂存区和工作目录, 重置暂存区和工作目录,回到最后一次提交后的状态。 …...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...

基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...