Springboot自动配置原理
1、引导加载自动配置类
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {}
1、@SpringBootConfiguration
实现是一个@Configuration,代表当前是一个配置类
2、@ComponentScan
指定扫描那些注解
3、@EnableAutoConfiguration
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}
(1)@AutoConfigurationPackage
自动配置包,指定了默认的包规则
@Import(AutoConfigurationPackages.Registrar.class) //给容器中导入一个组件
public @interface AutoConfigurationPackage {}
//利用Registrar给容器中导入一系列组件
//将指定的一个包下的所有组件导入进来,MainApplication 所在包下。
我们进入Registrar看一下,有这样一个方法
它会把当前注解所标注的类所在的包,也就是Springboot主程序入口所在包下的所有组件导入,也就是我们自定义的一些组件。
(2)@Import(AutoConfigurationImportSelector.class)
这个注解就是加载Springboot给我们配置好的一些组件。我们进入这个类来看一下。
首先是这样的一个方法
在这个方法中,主要调用getAutoConfigurationEntry(annotationMetadata)方法,我们又进入这个方法看下。
在这个方法中又主要调用List configurations = getCandidateConfigurations(annotationMetadata, attributes)来获取到所有需要导入到容器中的配置类,那它有事如何获取到的呢。我们又进入这个方法来看一下。
在这个方法当中又主要调用loadSpringFactories
我们看到它主要从classLoader.getResources(FACTORIES_RESOURCE_LOCATION);加载,也就是
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
中加载。
所以Springboot自动配置的流程如下:
1、利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
2、调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类
3、利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件
4、从META-INF/spring.factories位置来加载一个文件。
默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories
SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先
@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
}