一、自动配置的作用
1.将第三方的组件自动装载到IOC容器里面,不需要开发人员再去编写相关的配置,比如说我们在pom.xml中添加启动器spring-boot-starter-data-redis之后,我们就可以直接使用@Autowired来注入RedisTemplate,这就是自动配置的好处。
2.本文涉及到@Import注解的使用、SpringFactories机制
二、自动配置的原理
1.首先他是通过启动类上的@SpringBootApplication实现的,其中包含两个注解@SpringBootConfiguration、@EnableAutoConfiguration,而@SpringBootConfiguration可以看做@Configuration注解,主要实现自动配置的注解是@EnableAutoConfiguration
2.使用@Import并定义AutoConfigurationImportSelector来实现批量注册(不知道@Import作用的同学建议查一下该注解),然后我们点进去其中有个getAutoConfigurationEntry
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
3.进入该方法getCandidateConfigurations
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
configurations = this.removeDuplicates(configurations);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.getConfigurationClassFilter().filter(configurations);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}
4.可以看到他调用了SpringFactoriesLoader.loadFactoryNames方法,最终调用该类的loadSpringFactories,该方法可以让ClassLoader读取所有的jar包下的META-INF/spring.factories下的文件信息,该文件包含了第三方jar包所提供的@Configuration配置类的全限定类名
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
}
5.如在Spring-boot-autoconfigure模块的spring.factories中
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。