当前位置:网站首页>三、自动配置源码分析
三、自动配置源码分析
2022-08-05 05:16:00 【呆比特】
三、自动配置源码分析
要学习SpringBoot自动装配的原理,我们就应该从启动类开始。
首先第一个,启动类标注@SpringBootApplication注解,代表这是一个SpringBoot应用。@SpringBootApplication是一个合成注解,它包括@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan(“xxx”),我们来一个一个来看。

1. @SpringBootConfiguration
首先,进入到@SpringBootConfiguration,发现其里边就是一个@Configuration,这个我们已经很熟悉了,它就代表当前是一个配置类,这里也就不在多说了。

2. @ComponentScan
@ComponentScan也不必多说了吧,它用来指定包扫描路径。
3. @EnableAutoConfiguration
很显然,前两个都是我们所熟悉的,那么这里边最重要的很定就是@EnableAutoConfiguration了,既然压力给到了这边,那我们就来重点看看。

除去前边几个元注解,@EnableAutoConfiguration也主要包含两个重要的注解
3.1 @AutoConfigurationPackage

进入@AutoConfigurationPackage,发现里边就是一个@Import,意思就是给容器中注册一个Registrar组件

这里的作用其实是批量导入组件,由于Import一个一个导太麻烦了,干脆写一段代码来批量导入。那这里到底导入了什么呢,我们debug走起。

也就是说,这里是将MainApplication所在包下的所有组件批量导入进来
到这里,@AutoConfigurationPackage我们就搞清楚了,接下来看下一个。
3.2 @Import({AutoConfigurationImportSelector.class})
根据名称就可以明显的猜到,这里是利用Selector机制,想再给容器中导入一些东西,那么导入什么东西呢?我们进入到AutoConfigurationImportSelector类里边,可以看到一个叫 selectImports() 的方法,如下:
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
这个方法返回一个数组,就是我们指定要导入的东西,而这些东西都是调用getAutoConfigurationEntry()这个方法得到的,从autoConfigurationEntry得到所有的配置,转成String数组返回,所以,我们现在还主要分析 getAutoConfigurationEntry() 方法:

我们来看这个方法,首先红色框中的代码获取了一堆候选的configuration,然后经过排除、移除一系列操作,最后封装返回,那么,这一堆configuration是什么呢?我们来看看红框中的方法:



从这几段代码可以看出,这是利用工厂加载,用 loadSpringFactories() 方法,得到了所有的组件。想要知道从哪里得到的组件,就得来看这个方法。

从这个方法可以看到,我们从META-INF/spring.factories位置来加载一个文件,意思就是默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件,在这些文件中,有一个非常重要的包叫做spring-boot-autoconfigure-2.3.4.RELEASE.jar,我们来看一下这个包里边的META-INF/spring.factories文件:
现在明白了吧,其实就是在这个配置文件中写死了,只要springboot一启动,就要给容器中加载这些配置类。
虽然springboot一启动就一股脑的加载了这么多的配置类,但是在我们前边的测试中会发现,容器中就没有那么多呀?其实,虽然springboot一启动就一股脑的加载了这么多,但是并不是全部生效的,最终其实是按照条件装配规则@Conditional按需配置的。
比如这里我们用aop举个栗子,感兴趣的可以按照前边学习去分析。
总结
■ SpringBoot先加载所有的自动配置类(xxxAutoConfiguration)
■ 每个自动配置类按照条件进行生效,并默认绑定配置文件指定的值(xxxProperties和配置文件进行了绑定)
■ 生效的配置类就会给容器中装配很多组件
■ 只要容器中有这些组件,相当于这些功能就有了
■ 我们还可以定制化配置(直接自己@Bean替换底层的组件;修改配置文件)
自动配置的源码到这里就全部分析完啦,自己再好好品味一下吧!
边栏推荐
- 九、响应处理——内容协商底层原理
- 2021电赛资源及经验总结
- [Pytorch study notes] 11. Take a subset of the Dataset and shuffle the order of the Dataset (using Subset, random_split)
- Web Component-处理数据
- CVPR 2020 - 频谱正则化
- 【Promise高级用法】实现并行和串行API
- 【论文精读】R-CNN 之预测框回归(Bounding box regression)问题详述
- tensorflow的session和内存溢出
- CVPR 2022 | 70% memory savings, 2x faster training
- 数控直流电源
猜你喜欢

Tensorflow steps on the pit notes and records various errors and solutions
![[After a 12] No record for a whole week](/img/05/df9aeb04274e308e1341020f836821.jpg)
[After a 12] No record for a whole week

华科提出首个用于伪装实例分割的一阶段框架OSFormer

大型Web网站高并发架构方案

如何停止flink job

伪RTOS-ProroThread在CH573芯片上的移植

Thread handler handle IntentServvice handlerThread

基于STM32F407的一个温度传感器报警系统(用的是DS18B20温度传感器,4针0.96寸OLED显示屏,并且附带日期显示)

【Pytorch学习笔记】11.取Dataset的子集、给Dataset打乱顺序的方法(使用Subset、random_split)

数控直流电源
随机推荐
[Database and SQL study notes] 9. (T-SQL language) Define variables, advanced queries, process control (conditions, loops, etc.)
单变量线性回归
怎样在Disciples门徒获得收益?
原来何恺明提出的MAE还是一种数据增强
PoE视频监控解决方案
TinyFlashDB:一种超轻量的可纠错的通用单片机flash存储方案
CVPR 2022 |节省70%的显存,训练速度提高2倍
【shell编程】第三章:函数
发顶会顶刊论文,你应该这样写作
Thread handler handle IntentServvice handlerThread
【ts】typescript高阶:条件类型与infer
【Shell编程】第一章:子串
【论文精读】Rich Feature Hierarchies for Accurate Object Detection and Semantic Segmentation(R-CNN)
如何停止flink job
【ts】typescript高阶:分布式条件类型
CVPR最佳论文得主清华黄高团队提出首篇动态网络综述
Machine Learning (1) - Machine Learning Fundamentals
读论文-Cycle GAN
CAN、CAN FD
基于Flink CDC实现实时数据采集(三)-Function接口实现