Spring Boot自动装配原理

文章目录

  • SpringBoot的自动装配原理?
      • 一、@SpringBootConfiguration(SpringBoot的配置)
      • 二、@EnableAutoConfiguration(自动配置)
        • 1、@AutoConfigurationPackage(自动配置包)
        • 2、@Import({AutoConfigurationImportSelector.class})(自动导入选择)
          • 2.1、getAutoConfigurationEntry方法
          • 2.2、getCandidateConfigurations
          • 2.3、loadFactoryNames
          • 2.4、META-INF/spring.factories
          • 2.5、loadSpringFactories
          • 2.6、removeDuplicates和getExclusions
      • 三、@ComponentScan
      • 四、总图

SpringBoot的自动装配原理?

我感觉三言两语说不明白,还是先根据源码,然后再图解的方式梳理一下。

@SpringBootApplication // 标注这个类是一个SpringBoot的应用
public class Logback02Application {

    public static void main(String[] args) {
        // 将SpringBoot应用启动
        SpringApplication.run(Logback02Application.class, args);
    }
}

梦开始的地方,下面要追的源码也就是**@SpringBootApplication**中的东西了

Spring Boot自动装配原理_第1张图片

点进来以后就是这样子的,这里主要要了解的是@SpringBootConfiguration@EnableAutoConfiguration@ComonentScan

一、@SpringBootConfiguration(SpringBoot的配置)

Spring Boot自动装配原理_第2张图片

点进去@SpringBootConfiguration

Spring Boot自动装配原理_第3张图片

点进去@Configuration

  1. @SpringBootConfiguration:SpringBoot的配置类
  2. @Configuration:spring的配置类
  3. @Component:也是一个spring的组件

二、@EnableAutoConfiguration(自动配置)

Spring Boot自动装配原理_第4张图片

点进@EnableAutoConfiguration

1、@AutoConfigurationPackage(自动配置包)

Spring Boot自动装配原理_第5张图片

点进@AutoConfigurationPackage

@Import({AutoConfigurationPackages.Registrar.class}):自动配置包注册

2、@Import({AutoConfigurationImportSelector.class})(自动导入选择)

Spring Boot自动装配原理_第6张图片

点进AutoConfigurationImportSelecto

这里面有好多好多的东西,下面就说几个重要的

2.1、getAutoConfigurationEntry方法

Spring Boot自动装配原理_第7张图片
Spring Boot自动装配原理_第8张图片

2.2、getCandidateConfigurations

    点进getCandidateConfigurations,这个是getAutoConfigurationEntry里面的方法

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List<String> configurations = new ArrayList(SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()));
    ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).forEach(configurations::add);
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.");
    return configurations;
}

这个是getCandidateConfigurations方法,获取候选的配置

Spring Boot自动装配原理_第9张图片

进入getSpringFactoriesLoaderFactoryClass

Spring Boot自动装配原理_第10张图片

进入EnableAutoConfiguration

最终发现这个找的就是主启动类

2.3、loadFactoryNames

Spring Boot自动装配原理_第11张图片
      这个loadFactoryNames是getCandidateConfigurations的方法,获取所有的加载配置方法

2.4、META-INF/spring.factories

      这个也是getCandidateConfigurations中提到的,它是自动配置的核心文件,这里也写一下从哪里找到它

Spring Boot自动装配原理_第12张图片

2.5、loadSpringFactories

Spring Boot自动装配原理_第13张图片

private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
    Map<String, List<String>> result = (Map)cache.get(classLoader);
    if (result != null) {
        return result;
    } else {
        Map<String, List<String>> result = new HashMap();

        try {
            Enumeration<URL> urls = classLoader.getResources("META-INF/spring.factories");

            while(urls.hasMoreElements()) {
                URL url = (URL)urls.nextElement();
                UrlResource resource = new UrlResource(url);
                Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                Iterator var6 = properties.entrySet().iterator();

                while(var6.hasNext()) {
                    Map.Entry<?, ?> entry = (Map.Entry)var6.next();
                    String factoryTypeName = ((String)entry.getKey()).trim();
                    String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                    String[] var10 = factoryImplementationNames;
                    int var11 = factoryImplementationNames.length;

                    for(int var12 = 0; var12 < var11; ++var12) {
                        String factoryImplementationName = var10[var12];
                        ((List)result.computeIfAbsent(factoryTypeName, (key) -> {
                            return new ArrayList();
                        })).add(factoryImplementationName.trim());
                    }
                }
            }

            result.replaceAll((factoryType, implementations) -> {
                return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
            });
            cache.put(classLoader, result);
            return result;
        } catch (IOException var14) {
            throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var14);
        }
    }
}

这里就可以加载上面提到的META-INF/spring.factories的文件了

2.6、removeDuplicates和getExclusions

Spring Boot自动装配原理_第14张图片
这两个方法一个是移除重复的配置,一个是处理需要排除的配置

三、@ComponentScan

      扫描被@Component (@Service,@Controller)注解的 bean,注解默认会扫描启动类所在的包下所有的类 ,可以自定义不扫描某些 bean。如下图所示,容器中将排除TypeExcludeFilter和AutoConfigurationExcludeFilter

四、总图

Spring Boot自动装配原理_第15张图片

你可能感兴趣的:(分享,spring,boot,spring,java)