天天看點

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生成自動配置報告,可以顯示自動配置的資訊。

繼續閱讀