自动装配概念
在springboot中,当我们引入某个依赖,就可以直接使用依赖里面的类进行自动注入,不需要像ssm框架那样在xml文件中配置各种bean,然后进行关联。像这样我们称之为自动配置。
自动配置类就是一个普通的@Configuration配置类,通常会带有一些@Conditional条件注解,并且使用SpringFactoriesLoader机制去定位加载它们(并非都是如此,还有其他一些Spring固有的加载方式,比如通过@ComponentScan包扫描或者显式@Import方式都可以让它们被发现)。
自动装配实现及原理
在springboot启动类中有@SpringBootApplication注解,该注解包含了@EnableAutoConfiguration。
@EnableAutoConfiguration的作用就是导入AutoConfigurationImportSelector.class这个类。在spring中的配置类源码分析中,分析过@Import导入的类会当成配置类来解析,并且如果这个配置类是实现了DeferredImportSelector接口,就会调用selectImports方法。
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
try {
//解析加载spring-autoconfigure-metadata.properties
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
//获取@EnableAutoConfiguration的属性
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
//获取spring.factories中所有的AutoConfiguration
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
//去重(也就是按类名去重)
configurations = this.removeDuplicates(configurations);
configurations = this.sort(configurations, autoConfigurationMetadata);
//获取需要排除的AutoConfiguration,可以通过@EnableAutoConfiguration注解的exclude属性,或者spring.autoconfigure.exclude来配置
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
//排除
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
//获取spring.factories中的AutoConfigurationImportFilter对AutoConfiguration进行过滤,默认会拿到OnBeanCondition、OnClassCondition、OnWebApplicationCondition这三个会去判断上面的AutoConfiguration是否符合它们自身所要求的条件,不符合的会过滤掉,会利用spring-autoconfigure-metadata.properties中的配置来进行过滤。
configurations = this.filter(configurations, autoConfigurationMetadata);
//configurations表示合格的,exclusions表示被排除的,把它们记录在ConditionEvaluationReportAutoConfigurationImportListener中
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return StringUtils.toStringArray(configurations);
} catch (IOException var6) {
throw new IllegalStateException(var6);
}
}
}