SpringBoot自动装配原理解析

首先对于一个SpringBoot工程来说,最明显的标志的就是 @SpringBootApplication它标记了这是一个SpringBoot工程,所以今天的 SpringBoot自动装配原理也就是从它开始说起。

自动装配流程

首先我们来看下@SpringBootApplication 这个注解的背后又有什么玄机呢,我们按下 ctrl + 鼠标左键,轻轻的点一下,此时见证奇迹的时刻..
我们看到如下优雅的代码:

SpringBoot自动装配原理解析


这其中有两个比较容易引起我们注意的地方,一个是@SpringBootConfiguration注解,另一个是 @EnableAutoConfiguration注解;之所以说这个两个注解比较吸引我们的眼球, 不是因为它们长大的好看,而是因为其他的注解太难看了(主要是因为其他的注解我们都是比较熟悉,即使不知道他们是干什么的,可以肯定更自动装配是没有关系的)。 然后我们又伸出了邪恶的小手,开启了熟悉的操作,按下了Ctrt + 鼠标左键,瞪着色咪咪的小眼睛,瞳孔放大了百倍等待着奇迹的出现... 擦... 擦...擦...

SpringBoot自动装配原理解析


什么也没有...
那我要你有何用,这么顶级的世界级的开源项目,怎么会让一个没用的家伙存在呢? 于是动用了上亿的脑细胞大军,经过复杂的运算,得出了一个不靠谱的结论:它可能使用来标记这是一个SpringBoot工程的配置。因为SpringBootConfiguration 翻译过来就是SpringBoot的配置,于是心中又是几万只羊驼在万马奔腾,大漠飞扬。

气定神闲之后,秉承着·失败是成功之母"的信念, 熟练的左手行云流水般的按下了 Ctrl + Table 键,回到了最初的的地方。眼睛盯着 @EnableAutoConfiguration ,环顾左右,在地址栏输入了谷歌翻译, 结果显示 自动装配。我找的就是你,真是众里寻他千百度,那人却在灯火阑珊处。 熟练的按下了 Ctrl +左键,迫不及待的想要进入; 心里默默背诵起了《桃花源记》的经典诗句 ∶

林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗

SpringBoot自动装配原理解析


此时此刻心情愉悦,有过前面的经历之后,在面对新的世界时候,我们淡定了许多。 此时大脑高速运转,没有再纠结,直捣黄龙,进入了 AutoConfigurationImportSelector.class 类,因为谷歌翻译告诉我们,这个是自动配置导入选择器。 于是我们发现了—片新天地

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } // 获取自动配置的实体 AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); } // 具体用来加载自动配置类得方法 protected AutoConfigurationEntry getAutoConfigurationEntry(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, ); configurations.removeAll(exclusions); configurations = getConfigurationClassFilter().filter(configurations); fireAutoConfigurationImportEvents(configurations, exclusions); // 返回最终需要的配置 return new AutoConfigurationEntry(configurations, exclusions); } }

而这个自动配置的实体 AutoConfigurationEntry 里面有两个属性,configurations和 exclusions。

protected static class AutoConfigurationEntry { // 用来存储需要的配置项 private final List<String> configurations; // 用来存储排除的配置项 private final Set<String> exclusions; private AutoConfigurationEntry() { this.configurations = Collections.emptyList(); this.exclusions = Collections.emptySet(); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypsgw.html