zoukankan      html  css  js  c++  java
  • Spring Boot 自动配置原理

    加载

    SpringBoot应用启动的时候,从主方法进行启动

    @SpringBootApplication
    public class XxxApplication {
      public static void main(String[] args) {
        SpringApplication.run(XxxApplication.class, args);
      }
    }

    @SpringBootApplication是一个组合注解,包含如下注解

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(
        excludeFilters = {@Filter(
        type = FilterType.CUSTOM,
        classes = {TypeExcludeFilter.class}
    ), @Filter(
        type = FilterType.CUSTOM,
        classes = {AutoConfigurationExcludeFilter.class}
    )}
    )

    @EnableAutoConfiguration为开启自动配置,其也是组合注解,包含如下注解

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import({AutoConfigurationImportSelector.class})

    主要功能由@Import提供,其导入的AutoConfigurationImportSelector的selectImports方法

    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }

    调用getAutoConfigurationEntry方法

    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, 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.filter(configurations, autoConfigurationMetadata);
        this.fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
      }
    }

    调用getCandidateConfigurations方法

    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;
    }

    通过loadFactoryNames方法扫描spring.factories文件中包含的JAR文件,加载到Spring容器。

    public static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) {
        return loadMetadata(classLoader, "META-INF/spring-autoconfigure-metadata.properties");
    }

    生效

    这些自动配置类都是在某些条件下生效

    @ConditionalOnBean:当容器里有指定的bean的条件下
    @ConditionalOnMissingBean:当容器里不存在指定bean的条件下
    @ConditionalOnClass:当类路径下有指定类的条件下
    @ConditionalOnMissingClass:当类路径下不存在指定类的条件下
    @ConditionalOnProperty:指定的属性是否有指定的值
  • 相关阅读:
    创建基于 SQL Server 表的外部内容类型
    symfony入门之 app/console 命令
    git上传代码到github
    ubuntu下配置apache虚拟主机
    ubuntu14.04下解决编辑器无法输入中文
    PHP把域名解析为站点IP
    mysql平常总结
    php防sql注入函数
    常用的正则检测总结
    redis缓存注意事项
  • 原文地址:https://www.cnblogs.com/ityard/p/11134760.html
Copyright © 2011-2022 走看看