• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

SpringBoot自动装配流程

武飞扬头像
吃小露丸子。
帮助1

1.启动类上面有一个@SpringBootApplication这个注解,这个注解是一个组合注解。它包含很多注解,我们可以点进去一下。

  1.  
    @Target({ElementType.TYPE})
  2.  
    @Retention(RetentionPolicy.RUNTIME)
  3.  
    @Documented
  4.  
    @Inherited
  5.  
    @SpringBootConfiguration
  6.  
    @EnableAutoConfiguration
  7.  
    @ComponentScan(
  8.  
    excludeFilters = {@Filter(
  9.  
    type = FilterType.CUSTOM,
  10.  
    classes = {TypeExcludeFilter.class}
  11.  
    ), @Filter(
  12.  
    type = FilterType.CUSTOM,
  13.  
    classes = {AutoConfigurationExcludeFilter.class}
  14.  
    )}
  15.  
    )
学新通

主要涉及以下几个注解: 

@SpringBootConfiguration

作用:标记这个类是一个Springboot的配置类。

@ComponentScan

作用:自动扫描包(扫描当前主启动类同级的包)并加载符合条件的组件或者bean,将这个bean定义加载到IOC容器中。

@EnableAutoConfiguration

作用:开启自动配置功能

2.点击@EnableAutoConfiguration,进入到这个注解里面,有以下几个注解。

  1.  
    @Target({ElementType.TYPE})
  2.  
    @Retention(RetentionPolicy.RUNTIME)
  3.  
    @Documented
  4.  
    @Inherited
  5.  
    @AutoConfigurationPackage
  6.  
    @Import({AutoConfigurationImportSelector.class})
主要涉及以下几个注解:
@AutoConfigurationPackage

作用:自动注册包

@Import({AutoConfigurationImportSelector.class})

作用: 给容器导入组件

AutoConfigurationImportSelector.class

作用:自动配置导入选择器

3.点击AutoConfigurationImportSelector进入查看源码

  1.  
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
  2.  
    if (!this.isEnabled(annotationMetadata)) {
  3.  
    return NO_IMPORTS;
  4.  
    } else {
  5.  
    AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
  6.  
    return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
  7.  
    }
  8.  
    }

 selectImports()是AutoConfigurationImportSelector的核心函数,其核心功能就是获取spring.factories中EnableAutoConfiguration所对应的Configuration类列表。

  AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
看到selectImports方法里的这一行,我们点击继续查看进入到getAutoConfigurationEntry()这个方法,获取自动配置的实体。
  1.  
    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
  2.  
    if (!this.isEnabled(annotationMetadata)) {
  3.  
    return EMPTY_ENTRY;
  4.  
    } else {
  5.  
    AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
  6.  
    List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
  7.  
    configurations = this.removeDuplicates(configurations);
  8.  
    Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
  9.  
    this.checkExcludedClasses(configurations, exclusions);
  10.  
    configurations.removeAll(exclusions);
  11.  
    configurations = this.getConfigurationClassFilter().filter(configurations);
  12.  
    this.fireAutoConfigurationImportEvents(configurations, exclusions);
  13.  
    return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
  14.  
    }
  15.  
    }
学新通
此方法中有一个 this.getCandidateConfigurations(annotationMetadata, attributes); 获得候选配置的方法;点击这个方法进入到getCandidateConfiguration()这个方法。
  1.  
    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
  2.  
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
  3.  
    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.");
  4.  
    return configurations;
  5.  
    }
点击getSpringFactoriesLoaderFactoryClass()方法,这个方法,标注了EnableAutoConfiguration注解的类。
  1.  
    protected Class<?> getSpringFactoriesLoaderFactoryClass() {
  2.  
    return EnableAutoConfiguration.class;
  3.  
    }

getCandidateConfiguration()方法又调用SpringFactoriesLoader 类的静态方法!我们进入SpringFactoriesLoader类loadFactoryNames() 方法------->获取所有的加载配置。

  1.  
    public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
  2.  
    String factoryTypeName = factoryType.getName();
  3.  
    return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
  4.  
    }
在loadFactoryNames()方法看到这一行
  return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
我们继续点击查看 loadSpringFactories 方法
  1.  
    private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
  2.  
    MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
  3.  
    if (result != null) {
  4.  
    return result;
  5.  
    } else {
  6.  
    try {
  7.  
    Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
  8.  
    LinkedMultiValueMap result = new LinkedMultiValueMap();
  9.  
     
  10.  
    while(urls.hasMoreElements()) {
  11.  
    URL url = (URL)urls.nextElement();
  12.  
    UrlResource resource = new UrlResource(url);
  13.  
    Properties properties = PropertiesLoaderUtils.loadProperties(resource);
  14.  
    Iterator var6 = properties.entrySet().iterator();
  15.  
     
  16.  
    while(var6.hasNext()) {
  17.  
    Entry<?, ?> entry = (Entry)var6.next();
  18.  
    String factoryTypeName = ((String)entry.getKey()).trim();
  19.  
    String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
  20.  
    int var10 = var9.length;
  21.  
     
  22.  
    for(int var11 = 0; var11 < var10; var11) {
  23.  
    String factoryImplementationName = var9[var11];
  24.  
    result.add(factoryTypeName, factoryImplementationName.trim());
  25.  
    }
  26.  
    }
  27.  
    }
  28.  
     
  29.  
    cache.put(classLoader, result);
  30.  
    return result;
  31.  
    } catch (IOException var13) {
  32.  
    throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
  33.  
    }
  34.  
    }
  35.  
    }
学新通

loadSpringFactories 方法中的classLoader.getResources(“META-INF/spring.factories”) —》获取项目资源;

ClassLoader.getSystemResources(“META-INF/spring.factories”)—》获取系统资源。

项目资源和系统资源都是在"META-INF/spring.factories"文件中获取的。

总结

1.SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值。

2.将这些值作为自动配置类导入容器,自动配置类就会生效,帮助我们进行自动配置工作。

3.整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;

4.它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration),就是给容器中导入这个场景需要的所有组件,并配置好这些组件。

5.有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfkkkig
系列文章
更多 icon
同类精品
更多 icon
继续加载