前言
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文件中,每行一个配置,多个类名逗号分隔,而\表示忽略换行。
原理流程图: