面试题:springboot怎么实现自动配置的

我们写一个springboot项目的时候通过注解@SpringBootApplication来实现,程序的自动加载及扫描和springboot自身配置加载的
再具体一点:就是通过@SpringBootApplication中的@EableAutoConfiguration注解来实现的,
怎么实现的呢?
我们就需要看看源码,来了解@EableAutoConfiguration的实现原理了

面试题:springboot怎么实现自动配置的_第1张图片

@EnableAutoConfiguration是开启自动配置的注解,在创建的Spring Boot项目中并不能直接看到此注解,它是由组合注解@SpringBootApplication引入的。在Spring Boot入口类(除单元测试外)中,唯一的一个注解就是@SpringBootApplication。它是Spring Boot项目的核心注解,用于开启自动配置,准确说是通过该注解内组合的@EnableAutoConfiguration开启了自动配置。

在未使用Spring Boot的情况下,Bean的生命周期由Spring来管理,然而Spring无法自动配置@Configuration注解的类。而Spring Boot的核心功能之一就是根据约定自动管理该注解标注的类。用来实现该功能的组件之一便是@EnableAutoConfiguration注解。@EnableAutoConfiguration位于spring-boot-autoconfigure包内,当使用@SpringBootApplication注解时,@EnableAutoConfiguration注解会自动生效。@EnableAutoConfiguration的主要功能是启动Spring应用程序上下文时进行自动配置

@EnableAutoConfiguration注解提供了一个常量和两个成员参数的定义。
·ENABLED_OVERRIDE_PROPERTY:用来覆盖开启/关闭自动配置的功能。
·exclude:根据类(Class)排除指定的自动配置。
·excludeName:根据类名排除指定的自动配置。

AutoConfigurationImportSelector是实现自动配置的关键
AutoConfigurationImportSelector源码解析

@EnableAutoConfiguration的关键功能是通过@Import注解导入的ImportSelector来完成的。从源代码得知@Import(AutoConfigurationImportSelector.class)是@EnableAutoConfiguration注解的组成部分,也是自动配置功能的核心实现者。@Import的作用和xml配置中标签的作用一样,我们可以通过@Import引入@Configuration注解的类,也可以导入实现了ImportSelector或ImportBeanDefinitionRegistrar的类,还可以通过@Import导入普通的POJO(将其注册成Spring Bean,导入POJO需要Spring 4.2以上版本)。 @Import的许多功能都需要借助接口ImportSelector来实现,ImportSelector决定可引入哪些@Configuration。

当AutoConfigurationImportSelector被@Import注解引入之后,它的selectImports方法会被调用并执行其实现的自动装配逻辑。selectImports方法几乎涵盖了组件自动装配的所有处理逻辑。让我们来看看AutoConfigurationImportSelector的selectImports方法源代码。

对于importSelector来说,有两种形式
一种是实现 DeferredImportSelector,
一种是实现 ImportSelector。
DeferredImportSelector来说,不会通过调用 selectImports方法进行配置加载,
ImportSelector形式会通过selectImports方法进行配置加载;

DeferredImportSelector这种是先进行我们的 @Configruation配置的加载,然后进行其他(Autoconfig相关类)的加载;

ImportSelector先加载 Autoconfig相关类,然后加载@Configruation类。
主要是通过以下源码方法进行加载配置类

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
   // 是否开启自动配置
   if (!isEnabled(annotationMetadata)) {
      return EMPTY_ENTRY;
   }
   //获取注解的 属性(exclude 和 excludeName)
   AnnotationAttributes attributes = getAttributes(annotationMetadata);
   //获取自动配置类。从spring.factories 中获取
   List configurations = getCandidateConfigurations(annotationMetadata, attributes);
   configurations = removeDuplicates(configurations);
   //通过我们的注解属性,获取exclude的类
   Set exclusions = getExclusions(annotationMetadata, attributes);
   //检查 exclsions 里边的类是否是正规的类
   checkExcludedClasses(configurations, exclusions);
   configurations.removeAll(exclusions);
   //筛选 configurations
   configurations = getConfigurationClassFilter().filter(configurations);
      // 事件发布
   fireAutoConfigurationImportEvents(configurations, exclusions);
   return new AutoConfigurationEntry(configurations, exclusions);
}

你可能感兴趣的:(spring,boot,spring,java)