refresh和自动配置大致流程
如何自动配置
我们看下这段代码,红色框是什么放入的注册类,其实这就是我们要注册的配置类,自动装配跟他有关:
为什么呢,因为他头上有注解SpringBootApplication
:
所以其实你只要传一个头上有这个注解的类就可以了,不一定要是main
方法的类。
SpringBootApplication注解
那为什么就有这个注解就能自动配置呢,我们来看看这个注解,其他你可以不管,但是EnableAutoConfiguration
你得看:
首先这个是一个配置类,可以被解析,因为有SpringBootConfiguration
注解,被Configuration
注解了:
这样我们的SpringBootApplication
就类似于我们经常配置的java
配置类。有了这个前提,我们就可以先看这个配置类的解析过程,其实就是ConfigurationClassPostProcessor
的解析处理,解析流程我以前的spring
源码文章都讲过,其中processImports
的处理也特别讲过,会先递归获取所有import
进来的类,然后按不同类型进行判断处理,重点就是这里啦,我们先来看下EnableAutoConfiguration
注解是不是有import
呢。
EnableAutoConfiguration注解
有个AutoConfigurationImportSelector
被import,其实还有一个在AutoConfigurationPackage注解里,暂时不说,重点是AutoConfigurationImportSelector
。
AutoConfigurationImportSelector自动配置导入选择器
看下他的结构,左边不用管,就是为了回调拿到一些属性,好对容器操作,主要是右边,我们前面spring
的文章讲过ImportSelector的原理,想看的朋友可以看下这篇文章,有这个基础对下面的理解比较好,因为这里还有个DeferredImportSelector
,他会在ConfigurationClassParser
解析方法的最后来处理。
可以看到,他被处理的时候:
DeferredImportSelectorHandler
就是专门来处理这些DeferredImportSelector
的。
DeferredImportSelectorHandler的handle
首先会封装一个持有器DeferredImportSelectorHolder
,如果deferredImportSelectors
为空,表示在被DeferredImportSelectorGroupingHandler
处理中,DeferredImportSelectorGroupingHandler
又是什么呢,其实我们要处理的DeferredImportSelectorHolder
会根据Group
进行分组,来区分不同的ImportSelector
,比如我们这个自动装配的AutoConfigurationImportSelector
,是属于AutoConfigurationGroup
类型的,分组处理方便,到时候只需要遍历所有组中的ImportSelector
统一处理即可。因为处理的方式是迭代器循环,所以不能添加,只能直接处理,当然如果不为空,表示没有在处理,可以添加到deferredImportSelectors
集合里。
public void handle(ConfigurationClass configClass, DeferredImportSelector importSelector) {
DeferredImportSelectorHolder holder = new DeferredImportSelectorHolder(configClass, importSelector);
if (this.deferredImportSelectors == null) {//直接处理
DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
handler.register(holder);
handler.processGroupImports();
}
else {
this.deferredImportSelectors.add(holder);//添加
}
}
DeferredImportSelectorGroupingHandler的register注册DeferredImportSelectorHolder
可以看到组处理器里面会有一个groupings
映射,就是来存放Group
类别和DeferredImportSelectorGrouping
映射的,同一个Group
类别里面可以很多个DeferredImportSelectorGrouping
,因为DeferredImportSelectorGrouping
里面有集合。
//自动装配类型和组映射
private final Map<Object, DeferredImportSelectorGrouping> groupings = new LinkedHashMap<>();
//注解属性和配置类的映射
private final Map<AnnotationMetadata, ConfigurationClass> configurationClasses = new HashMap<>();
//注册分组
public void register(DeferredImportSelectorHolder deferredImport) {
Class<? extends Group> group = deferredImport.getImportSelector().getImportGroup();
DeferredImportSelectorGrouping grouping = this.groupings.computeIfAbsent(
(group != null ? group : deferredImport),
key -> new DeferredImportSelectorGrouping(createGroup(group)));//创建组
grouping.add(deferredImport);//创建一个组,并加入DeferredImportSelectorHolder
this.configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getConfigurationClass());//将注解属性和ConfigurationClass映射
}
DeferredImportSelectorGrouping
这里就是同一个组的会添加进deferredImports
集合。
其实是比较绕的,绕了几层,我画个图看了清晰:
后面将注册后怎么处理processGroupImports
。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。