当前位置:网站首页>三、自动配置源码分析
三、自动配置源码分析
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替换底层的组件;修改配置文件)
自动配置的源码到这里就全部分析完啦,自己再好好品味一下吧!
边栏推荐
- Oracle压缩表修改字段的处理方法
- AIDL detailed explanation
- 【ts】typescript高阶:条件类型与infer
- 5G中切片网络的核心技术FlexE
- A deep learning code base for Xiaobai, one line of code implements 30+ attention mechanisms.
- 单片机按键开发库-支持连击、长按等操作
- Thread handler handle IntentServvice handlerThread
- Day1:用原生JS把你的设备变成一台架子鼓!
- 【ts】typescript高阶:映射类型与keyof
- IT系统运行维护方法及策略
猜你喜欢
记我的第一篇CCF-A会议论文|在经历六次被拒之后,我的论文终于中啦,耶!
IJCAI 2022|边界引导的伪装目标检测模型BGNet
【Kaggle项目实战记录】一个图片分类项目的步骤和思路分享——以树叶分类为例(用Pytorch)
【数据库和SQL学习笔记】8.SQL中的视图(view)
[Kaggle project actual combat record] Steps and ideas sharing of a picture classification project - taking leaf classification as an example (using Pytorch)
全尺度表示的上下文非局部对齐
神经网络也能像人类利用外围视觉一样观察图像
物联网:LoRa无线通信技术
CVPR 2022 | 70% memory savings, 2x faster training
6k+ star,面向小白的深度学习代码库!一行代码实现所有Attention机制!
随机推荐
[Skill] Long-term update
基于Flink CDC实现实时数据采集(二)-Source接口实现
解决:Unknown column ‘id‘ in ‘where clause‘ 问题
全尺度表示的上下文非局部对齐
Service
SharedPreferences and SQlite database
SharedPreferences和SQlite数据库
华科提出首个用于伪装实例分割的一阶段框架OSFormer
【22李宏毅机器学习】课程大纲概述
网络信息安全运营方法论 (上)
【Pytorch学习笔记】8.训练类别不均衡数据时,如何使用WeightedRandomSampler(权重采样器)
沁恒MCU从EVT中提取文件建立MounRiver独立工程
WCH系列芯片CoreMark跑分
MySQL
吞吐?带宽?傻傻分不清楚
【论文阅读-表情捕捉】ExpNet: Landmark-Free, Deep, 3D Facial Expressions
【数据库和SQL学习笔记】8.SQL中的视图(view)
PID详解
[Pytorch study notes] 11. Take a subset of the Dataset and shuffle the order of the Dataset (using Subset, random_split)
AIDL详解