当前位置:网站首页>三、自动配置源码分析
三、自动配置源码分析
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替换底层的组件;修改配置文件)
自动配置的源码到这里就全部分析完啦,自己再好好品味一下吧!
边栏推荐
猜你喜欢
全尺度表示的上下文非局部对齐
【数据库和SQL学习笔记】8.SQL中的视图(view)
【Pytorch学习笔记】10.如何快速创建一个自己的Dataset数据集对象(继承Dataset类并重写对应方法)
原来何恺明提出的MAE还是一种数据增强
【Pytorch学习笔记】8.训练类别不均衡数据时,如何使用WeightedRandomSampler(权重采样器)
PoE视频监控解决方案
哥廷根大学提出CLIPSeg,能同时作三个分割任务的模型
Kubernetes常备技能
The University of Göttingen proposed CLIPSeg, a model that can perform three segmentation tasks at the same time
网络ID,广播地址,掩码位数计算
随机推荐
CVPR 2022 |节省70%的显存,训练速度提高2倍
flink项目开发-flink的scala shell命令行交互模式开发
OSPF故障排除办法
网络ID,广播地址,掩码位数计算
A deep learning code base for Xiaobai, one line of code implements 30+ attention mechanisms.
【nodejs】第一章:nodejs架构
《基于机器视觉的输电线路交叉点在线测量方法及技术方案》论文笔记
【22李宏毅机器学习】课程大纲概述
SQL (2) - join window function view
表情捕捉的指标/图像的无参考质量评价
沁恒MCU从EVT中提取文件建立MounRiver独立工程
PoE视频监控解决方案
Service
【Shell编程】第一章:子串
CVPR2021 - Inception Convolution with Efficient Dilation Search
华科提出首个用于伪装实例分割的一阶段框架OSFormer
【ts】typescript高阶:联合类型与交叉类型
Tensorflow steps on the pit notes and records various errors and solutions
如何组织一场安全、可靠、高效的网络实战攻防演习?
轻松接入Azure AD+Oauth2 实现 SSO