天天看点

Spring Boot—— 自动配置原理

作者:程序员小橙

为什么 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—— 自动配置原理

总结 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生成自动配置报告,可以显示自动配置的信息。

继续阅读