Java教程

SpringBoot是如何实现自动配置的?--SpringBoot源码(四)

本文主要是介绍SpringBoot是如何实现自动配置的?--SpringBoot源码(四),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

注:该源码分析对应SpringBoot版本为2.1.0.RELEASE

1 前言

本篇接 助力SpringBoot自动配置的条件注解ConditionalOnXXX分析--SpringBoot源码(三)

温故而知新,我们来简单回顾一下上篇的内容,上一篇我们分析了SpringBoot的条件注解@ConditionalOnXxx的相关源码,现挑重点总结如下:

  1. SpringBoot的所有@ConditionalOnXxx的条件类OnXxxCondition都是继承于SpringBootCondition基类,而SpringBootCondition又实现了Condition接口。
  2. SpringBootCondition基类主要用来打印一些条件注解评估报告的日志,这些条件评估信息全部来源于其子类注解条件类OnXxxCondition,因此其也抽象了一个模板方法getMatchOutcome留给子类去实现来评估其条件注解是否符合条件。
  3. 前一篇我们也还有一个重要的知识点还没分析,那就是跟过滤自动配置类逻辑有关的AutoConfigurationImportFilter接口,这篇文章我们来填一下这个坑。

前面我们分析了跟SpringBoot的自动配置息息相关内置条件注解@ConditionalOnXxx后,现在我们就开始来撸SpringBoot自动配置的相关源码了。

2 @SpringBootApplication注解

在开始前,我们先想一下,SpringBoot为何一个标注有@SpringBootApplication注解的启动类通过执行一个简单的run方法就能实现SpringBoot大量Starter的自动配置呢? 其实SpringBoot的自动配置就跟@SpringBootApplication这个注解有关,我们先来看下其这个注解的源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration 
@ComponentScan(excludeFilters = { 
		@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
// ...省略非关键代码
}
复制代码

@SpringBootApplication标注了很多注解,我们可以看到其中跟SpringBoot自动配置有关的注解就有一个即@EnableAutoConfiguration,因此,可以肯定的是SpringBoot的自动配置肯定跟@EnableAutoConfiguration息息相关(其中@ComponentScan注解的excludeFilters属性也有一个类AutoConfigurationExcludeFilter,这个类跟自动配置也有点关系,但不是我们关注的重点)。 现在我们来打开@EnableAutoConfiguration注解的源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
	Class<?>[] exclude() default {};
	String[] excludeName() default {};
}
复制代码

看到@EnableAutoConfiguration注解又标有@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)两个注解,顾名思义,@AutoConfigurationPackage注解肯定跟自动配置的包有关,而AutoConfigurationImportSelector则是跟SpringBoot的自动配置选择导入有关(Spring中的ImportSelector是用来导入配置类的,通常是基于某些条件注解@ConditionalOnXxxx来决定是否导入某个配置类)。

因此,可以看出AutoConfigurationImportSelector类是我们本篇的重点,因为SpringBoot的自动配置肯定有一个配置类,而这个配置类的导入则需要靠AutoConfigurationImportSelector这个哥们来实现。

接下来我们重点来看AutoConfigurationImportSelector这个类,完了我们再简单分析下@AutoConfigurationPackage这个注解的逻辑。

3 如何去找SpringBoot自动配置实现逻辑的入口方法?

可以肯定的是SpringBoot的自动配置的逻辑肯定与AutoConfigurationImportSelector这个类有关,那么我们该如何去找到SpringBoot自动配置实现逻辑的入口方法呢?

在找SpringBoot自动配置实现逻辑的入口方法前,我们先来看下AutoConfigurationImportSelector的相关类图,好有个整体的理解。看下图:

图1

可以看到AutoConfigurationImportSelector重点是实现了DeferredImportSelector接口和各种Aware接口,然后DeferredImportSelector接口又继承了ImportSelector接口。

自然而然的,我们会去关注AutoConfigurationImportSelector复写DeferredImportSelector接口的实现方法selectImports方法,因为selectImports方法跟导入自动配置类有关,而这个方法往往是程序执行的入口方法。经过调试发现selectImports方法很具有迷惑性,se

这篇关于SpringBoot是如何实现自动配置的?--SpringBoot源码(四)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!