10、SpringBoot 源码分析 - 自动配置深度分析三

news2024/9/21 5:51:08

SpringBoot 源码分析 - 自动配置深度分析三

  • refresh和自动配置大致流程
  • AutoConfigurationImportSelector的getAutoConfigurationEntry获取自动配置实体(重点)
    • AutoConfigurationImportSelector的getCandidateConfigurations获取EnableAutoConfiguration类型的名字集合
    • AutoConfigurationImportSelector的removeDuplicates去重
    • AutoConfigurationImportSelector的getExclusions获取要排除的
    • AutoConfigurationImportSelector的checkExcludedClasses检查要排除的
    • AutoConfigurationImportSelector的filter过滤

refresh和自动配置大致流程

在这里插入图片描述

AutoConfigurationImportSelector的getAutoConfigurationEntry获取自动配置实体(重点)

前面讲了那么多,都是为了这里啊,不然直接上来都不知道是怎么来的,我们来看看这个干了什么,别看就那么点,其实里面很复杂,简单的说就是从我们初始化加载的所有的jar包下的META-INF/spring.factories属性中找到org.springframework.boot.autoconfigure.EnableAutoConfiguration属性,其实这个时候以及有缓存啦,前面初始化的时候已经全加载过了。然后进行去重,再获取要排除的名字,检查排除的类的合理性,然后排除,再进行条件类过滤,因为可能有些配置类缺少某些类就不能用了,触发自动装配导入事件,最后封装成AutoConfigurationEntry返回。

protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
			AnnotationMetadata annotationMetadata) {
   
     
		if (!isEnabled(annotationMetadata)) {
   
     
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);//获取自动装配类
		configurations = removeDuplicates(configurations);//去重
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);//获取要排除的
		checkExcludedClasses(configurations, exclusions);//检查要排除的
		configurations.removeAll(exclusions);//排除
		configurations = filter(configurations, autoConfigurationMetadata);//过滤
		fireAutoConfigurationImportEvents(configurations, exclusions);//触发导入事件
		return new AutoConfigurationEntry(configurations, exclusions);
	}

主要自动配置类都在这里,当然我们可以自定义,后面我们会自定义一个:
在这里插入图片描述

AutoConfigurationImportSelector的getCandidateConfigurations获取EnableAutoConfiguration类型的名字集合

这个代码我们前面很熟悉啊,就不多说了,从缓存中加载对应EnableAutoConfiguration类型的类名字,最终加载了124个,好多啊,没关系,后面过滤就没那么多了。

在这里插入图片描述

AutoConfigurationImportSelector的removeDuplicates去重

这个很巧妙,放进Set里又拿出来放进List里:

	protected final <T> List<T> removeDuplicates(List<T> list) {
   
		return new ArrayList<>(new LinkedHashSet<>(list));
	}

AutoConfigurationImportSelector的getExclusions获取要排除的

其实就是从注解属性的excludeexcludeName获取,当然还有个环境配置属性spring.autoconfigure.exclude也可以,就是说可以在yml或者propertise里配啦,其他就不多说了。
在这里插入图片描述
在这里插入图片描述

AutoConfigurationImportSelector的checkExcludedClasses检查要排除的

其实就是看下要排除的在不在自动配置集合里,有不在的就报异常,可能要排除的并不是自动配置的类,表示无效排除:

	private void checkExcludedClasses(List<String> configurations, Set<String> exclusions) {
   
     
		List<String> invalidExcludes = new ArrayList<>(exclusions.size());
		for (String exclusion : exclusions) {
   
     
			if (ClassUtils.isPresent(exclusion, getClass().getClassLoader()) && !configurations.contains(exclusion)) {
   
     
				invalidExcludes.add(exclusion);//不在自动配置类里,还要排除的,属于无效排除,要抛异常
			}
		}
		if (!invalidExcludes.isEmpty()) {
   
     
			handleInvalidExcludes(invalidExcludes);
		}
	}

	protected void handleInvalidExcludes(List<String> invalidExcludes) {
   
     
		StringBuilder message = new StringBuilder();
		for (String exclude : invalidExcludes) {
   
     
			message.append("\t- ").append(exclude).append(String.format("%n"));
		}
		throw new IllegalStateException(String.format(
				"The following classes could not be excluded because they are not auto-configuration classes:%n%s",
				message));
	}

AutoConfigurationImportSelector的filter过滤

这里会获取过滤器,其实就是OnClassConditionOnWebApplicationConditionOnBeanCondition这几个条件,他会去配置类的注解上查找相应的条件类是否存在,不存在就会被过滤掉,过滤的时候可能会开启线程,帮助一起处理,因为配置类数量多。如果多核的话,会用启动一个线程去分担一半数量的检查,会判断条件类是否能加载到,不能就被过滤掉了,如果用多个线程可能效果不太好,spring团队应该做过实验,2个最好。

private List<String> filter(List<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) {
	long startTime = System.nanoTime();
	// 转换自动配置类的List集合为String数组
	String[] candidates = StringUtils.toStringArray(configurations);
	// 存储最终的匹配结果,和candidates数组索引位置一一对应,true代表最终需要
	// 自动引入,false代表不需要自动引入
	boolean[] skip = new boolean[candidates.length];
	boolean skipped = false;
	// <AutoConfigurationImportSelector#filter_1>见详细讲解
	for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) {
		// <AutoConfigurationImportSelector#filter_2>见详细讲解
		invokeAwareMethods(filter);
		// <AutoConfigurationImportSelector#filter_3>见详细讲解
		boolean[] match = filter.match(candidates, autoConfigurationMetadata);
		// 循环当前的自动引入过滤器过滤结果,并记录过滤结果,用于后续逻辑过滤使用
		for (int i = 0; i < match.length; i++) {
			if (!match[i]) {
				skip[i] = true;
				candidates[i] = null;
				skipped = true;
			}
		}
	}
	// 当没有需要过滤的自动配置类时,会进if直接返回,否则执行后续逻辑,通过布尔数组进行过滤
	if (!skipped) {
		return configurations;
	}
	// 存储过滤后需要自动配置的类
	List<String> result = new ArrayList<>(candidates.length);
	for (int i = 0; i < candidates.length; i++) {
		// 如果当前位置为fasle则说明不需要跳过,则添加到最终结果中
		if (!skip[i]) {
			result.add(candidates[i]);
		}
	}
	// <AutoConfigurationImportSelector#filter_4>见详细讲解
	if (logger.isTraceEnabled()) {
		int numberFiltered = configurations.size() - result.size();
		logger.trace("Filtered " + numberFiltered + " auto configuration class in "
				+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms");
	}
	// 返回结果,不知道为什么要再重新new一个
	return new ArrayList<>(result);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1685823.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一个超级简单的Python UI库:NiceGUI

大家好&#xff0c;图形用户界面&#xff08;GUI&#xff09;的开发往往被看作是一项复杂且繁琐的任务。Python作为一门强大的编程语言&#xff0c;提供了许多优秀的库来帮助开发者实现这一目标。今天&#xff0c;我们将介绍一个名为NiceGUI的库&#xff0c;它能帮助你轻松构建…

基于Tensorflow+Keras的卷积神经网络(CNN)人脸识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 人脸识别是计算机视觉领域的一个重要研究方向&#xff0c;广泛应用于安全监控、身份验证、人机…

弘君资本股市资讯:深夜,利空突袭!美股大跳水!

昨夜&#xff0c;两大利空音讯突袭美股。 隔夜&#xff0c;最新披露的两则数据引发商场忧虑。其一是&#xff0c;美国5月Markit归纳PMI初值报54.4&#xff0c;创25个月新高&#xff0c;大幅高于预期的51.2&#xff0c;前值为51.3&#xff1b;其二是&#xff0c;在到5月18日的一…

05Django项目--前端公共文件和其他html文件的适配

对应视频链接点击直达 Django项目--前端公共文件和其他html文件的适配 对应视频链接点击直达前端页面准备Pubilc页面设置 OVER&#xff0c;不会有人不会吧不会的加Q1394006513结语 接着上一节 前端页面准备 为了方便大家更好的复制&#xff0c;我把整个项目及templates文件夹和…

docker如何拉取redis最新镜像并运行

要拉取Docker Hub上最新版本的Redis镜像&#xff0c;您可以使用以下命令&#xff1a; docker pull redis:latest 这里的latest标签会自动获取Redis镜像的最新版本。如果您希望指定一个确切的版本号&#xff0c;可以直接使用该版本号替换latest。例如&#xff0c;要拉取Redis版…

C++ (week5):Linux系统编程2:进程

文章目录 二、进程1.CPU的虚拟化2.进程命令(1)ps 3.进程的基本操作 (API)(1)获取进程的标识 (获得进程id)&#xff1a;getpid、getppid(2)创建进程&#xff1a;fork()(3)终止进程&#xff1a;exit()、_exit()、abort()、wait()、waitpid()①正常终止&#xff1a;exit()、_exit(…

Redis 源码学习记录:散列 (dict)

散列 Redis 源码版本&#xff1a;Redis-6.0.9&#xff0c;本篇文章的代码均在 dict.h / dict.c 文件中。 散列类型可以存储一组无需的键值对&#xff0c;他特别适用于存储一个对象数据。 字典 Redis 通常使用字典结构体存储用户散列数据。字典是 Redis 的重要数据结构。除了散…

AGM AG32 (MCU + FPGA)在音频处理上的应用案例

AGM AG32 (MCU FPGA)在音频处理&#xff0c;比如语音识别、降噪、声音增强等方面上的应用很多&#xff0c;结合AG32的特点&#xff0c;这里做一个简单的分享。 AGM AG32的架构是FPGA MCU&#xff0c;并且AG32与STM32的关键兼容&#xff0c;这个低成本的AG32器件&#xff0c;在…

MongoDB基础入门到深入(八)MongoDB整合SpringBoot、Chang Streams

文章目录 系列文章索引十五、MongoDB整合SpringBoot1、环境准备2、集合操作3、文档操作&#xff08;1&#xff09;相关注解&#xff08;2&#xff09;创建实体&#xff08;3&#xff09;添加文档&#xff08;4&#xff09;查询文档&#xff08;5&#xff09;更新文档&#xff0…

paligemma、Grounding-DINO-1.5简单无需标注无需训练直接可以使用的VLM图像到文本模型

1、paligemma 参考:https://github.com/google-research/big_vision/blob/main/big_vision/configs/proj/paligemma/README.md 模型架构: 文本与图像特征一起送入大模型 在线体验网址: https://huggingface.co/spaces/big-vision/paligemma 通过文字prompt既可与图片对话…

工行音视频服务平台建设与应用经验

近些年来&#xff0c;伴随着技术能力的积累突破&#xff0c;音视频服务开始蓬勃生长走进千家万户&#xff0c;使用远程视频通话、观看各类视频直播逐渐成为人们的日常&#xff0c;而金融服务作为社会生活的重要组成部分&#xff0c;自然需要积极拥抱应用新技术。 如今&#xff…

目标检测——无人机垃圾数据集

引言 亲爱的读者们&#xff0c;您是否在寻找某个特定的数据集&#xff0c;用于研究或项目实践&#xff1f;欢迎您在评论区留言&#xff0c;或者通过公众号私信告诉我&#xff0c;您想要的数据集的类型主题。小编会竭尽全力为您寻找&#xff0c;并在找到后第一时间与您分享。 …

【C++入门】—— C++入门 (下)_内联函数

前言&#xff1a;在了解完前面的C基础内容后&#xff0c;马上我们就要真正不如C的学习了&#xff0c;但在之前让我们最后了解最后一点点C入门知识&#xff01;来迟的520特别篇&#xff01; 本篇主要内容&#xff1a; 内联函数 auto关键字 范围for 指针空值nullptr C入门 1. 内联…

Science| 单体耦合纤维实现无芯片纺织电子(纤维器件/智能织物/柔性可穿戴电子)

东华大学Hongzhi Wang,Chengyi Hou和Qinghong Zhang团队在《Science》上发布了一篇题为“Single body-coupled fiber enables chipless textile electronics”的论文。论文内容如下: 一、 摘要 智能纺织品为将技术融入日常生活中提供了理想的平台。然而,目前的纺织电子系统…

飞凌嵌入式亮相上海CPSE,展现智能充储技术新力量

5月22日~24日&#xff0c;第三届上海国际充电桩及换电站展览会(CPSE)在上海汽车会展中心举行&#xff0c;飞凌嵌入式以“聚焦充电桩主控智造赋能车桩智联”为主题参展&#xff0c;与来自全国的客户朋友及行业伙伴一同交流分享&#xff0c;展位号Z15。 作为国内较早从事嵌入式技…

HTTPS:安全网络通信的基石

在数字化时代&#xff0c;网络通信的安全变得至关重要。HTTPS&#xff08;超文本传输安全协议&#xff09;是一种用于保护网络通信的协议&#xff0c;它通过加密技术确保数据传输的安全性和完整性。下面我们就来了解一下HTTPS。 一、HTTPS是什么&#xff1f; HTTPS是HTTP&…

罗德与施瓦茨FPS7频谱分析仪怎么判断真实信号?

频谱分析仪是电子测量领域的重要仪器&#xff0c;可以帮助工程师、研究人员分析信号的频域特性&#xff0c;为设备调试、故障诊断等提供有价值的数据支持。作为业界领先的频谱分析仪制造商&#xff0c;罗德与施瓦茨的FPS7型号在精度、灵敏度和分辨率等指标上都有出色表现&#…

《最新出炉》系列初窥篇-Python+Playwright自动化测试-39-highlight() 方法之追踪定位

1.简介 在之前的文章中宏哥讲解和分享了&#xff0c;为了看清自动化测试的步骤&#xff0c;通过JavaScript添加高亮颜色&#xff0c;就可以清楚的看到执行步骤了。在学习和实践Playwright的过程中&#xff0c;偶然发现了使用Playwright中的highlight()方法也突出显示Web元素。…

macOS Monterey 12.7.5 (21H1222) 正式版发布,ISO、IPSW、PKG 下载

macOS Monterey 12.7.5 (21H1222) 正式版发布&#xff0c;ISO、IPSW、PKG 下载 5 月 13 日凌晨&#xff0c;macOS Sonoma 14.5 发布&#xff0c;同时带来了 macOS Ventru 13.6.7 和 macOS Monterey 12.7.5 安全更新。 本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Appli…

【qt】QListWidget 组件

QListWidget 组件 一.QListWidget的用途二.界面设计三.QListWidget的添加1.界面添加2.代码添加 四.列表项的设置1.文本2.图标3.复选框4.列表大小 五.字体和图标的设置1.字体&#xff1a;2.图标&#xff1a; 六.设置显示模式1.图标2.列表 七.其他功能实现1.删除2.全选3.反选4.ad…