为什么 Spring Boot 不用配置,也能运行相关组件?
@SpringBootApplication --> @EnableAutoConfiguration -> @Import({AutoConfigurationImportSelector.class}) ,我们一步一步往下走:
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
autoConfigurationMetadata, annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
然后selectImports --> getAutoConfigurationEntry --> getCandidateConfigurations
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
然后一层层的跟踪,在 getCandidateConfigurations 中,是 spring先生产再配置信息。getSpringFactoriesLoaderFactoryClass 方法返回了EnableAutoConfiguration.class。
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
loadFactoryNames 方法调用 loadSpringFactories 方法,首先加载了 META-INF/spring.factories 配置文件,再整合到一起返回,调用了 map 的 getOrDefault 这两个方法, 根据 key 获取一个list。key是通过 getSpringFactoriesLoaderFactoryClass 方法获取的 EnableAutoConfiguration.class 的全路径名: org.springframework.boot.autoconfigure.EnableAutoConfiguration。
在 spring-boot 和spring-boot-autoconfigure中找到META-INF/spring.factories,,在 spring-boot-autoconfigure 的配置文件中找到 org.springframework.boot.autoconfigure.EnableAutoConfiguration。这里的类就是自动配置的类。
总结 Spring Boot 做了些什么:
通过注解: @SpringBootApplication --> @EnableAutoConfiguration -> @Import({AutoConfigurationImportSelector.class}) ,最终引入了 AutoConfigurationImportSelector 这个类,加载了 META-INF/spring.factories 文件,返回了 org.springframework.boot.autoconfigure.EnableAutoConfiguration 配置的信息(类)。
以 WebMvcAutoConfiguration 自动配置类为例子,了解这些自动配置类做了些什么:
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
- @ Configuration,表明这个是一个配置信息的类,就是相当于老版本的 xml 配置方式;
- @Conditional,这些是用于判断是否自动配置;
- after 是配置完毕之后进行的,像配置 DispatcherServletAutoConfiguration,这个是 mvc 的,都执行完毕之后,再调用 ValidationAutoConfiguration 对它进行验证。
-
在类主体中,有 @ConditionalOnProperty 注解,表明我们可以在配置文件中指定相应的值,然后自动配置类就通过这些配置去做出相应的反应,像加载相应功能等等。
总结:
- Spring Boot 框架不是重复的无用功,这些自动配置类都可以理解为对其他框架的整合。
-
通过注解 @SpringBootApplication --> @EnableAutoConfiguration -> @Import({AutoConfigurationImportSelector.class}) ,再从 META-INF/spring.factories 配置文件中返回自动配置类。
Tips:
- 配置类可以配置哪些信息,在对应的 ***Properties类中有声明。
- 可以设置 debug = true生成自动配置报告,可以显示自动配置的信息。