SpringBoot自动配置原理

1,191 阅读2分钟

前言

SpringBoot的核心是自动配置,而自动配置是基于条件判断来配置Bean的。关于自动配置的源码在spring-boot-autoconfigure-2.x.x.RELEASE.jar

在说自动配置之前先回顾一下springboot的运行原理

SpringBoot启动流程

  • SpringApplication.run中执行了两步操作,先封装了一个SpringApplication的实例,再执行该实例的重载run方法。
  • SpringApplication封装实例时,读取了classpath下所有的METE-INF/spring.factories xml配置文件的ApplicationContextInitializer(容器初始化器)还有ApplicationListener(侦听器),将这两者封装到SpringApplication实例中
  • 执行SpringApplication实例的run方法
  • run方法中默认初始化了Annotation配置的容器AnnotationConfigApplicationContext
  • 执行上面ApplicationContextInitializer的initial方法
  • 然后加载Bean到容器中

SpringBoot自动配置实现原理

在SpringBoot的启动类上可以看到@SpringBootApplication这个注解,点进去看一下这个组合注解的构成

@SpringBootApplication
public class SpringbootWorkApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootWorkApplication.class, args);
    }
}

@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 的主配置类,SpringBoot 通过运行这个类的 main 方法来启动 SpringBoot 应用。@SpringBootApplication 主要包含3个注解

  • @SpringBootConfiguration 里面是@Configuration,标记当前类是配置类
  • @EnableAutoConfiguration 开启自动配置
  • @ComponentScan 扫描主类所在的同级包以及下级包里的Bean

关键是@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 {};
}

最关键的要属@Import(EnableAutoConfigurationImportSelector.class),借助EnableAutoConfigurationImportSelector,@EnableAutoConfiguration 可以帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IOC容器。通过@Import(AutoConfigurationImportSelector.class)导入的配置功能,AutoConfigurationImportSelector 中的方法 getCandidateConfigurations,得到待配置的class的类名集合,这个集合就是所有需要进行自动配置的类,而是否配置的关键在于META-INF/spring.factories 文件中是否存在该配置信息。

  protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
            AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
                getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
        Assert.notEmpty(configurations,
                "No auto configuration classes found in META-INF/spring.factories. If you "
                        + "are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

如下图可以看到所有需要配置的类全路径都在spring.factories文件中,每行一个配置,多个类名逗号分隔,而\表示忽略换行。

原理流程图: