SpringBoot 自动配置原理了解吗?

SpringBoot 开启自动配置的注解是@EnableAutoConfiguration ,启动类上的注解@SpringBootApplication是一个复合注解,包含了@EnableAutoConfiguration:

  • EnableAutoConfiguration 只是一个简单的注解,自动装配核心功能的实现实际是通过 AutoConfigurationImportSelector

    @AutoConfigurationPackage //将main同级的包下的所有组件注册到容器中
    @Import({AutoConfigurationImportSelector.class}) //加载自动装配类 xxxAutoconfiguration
    public @interface EnableAutoConfiguration {
        String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    
        Class<?>[] exclude() default {};
    
        String[] excludeName() default {};
    }
  • AutoConfigurationImportSelector实现了ImportSelector接口,这个接口的作用就是收集需要导入的配置类,配合@Import()就可以将相应的类导入到 Spring 容器中
  • 获取注入类的方法是 selectImports(),它实际调用的是getAutoConfigurationEntry,这个方法是获取自动装配类的关键,主要流程可以分为这么几步:

    1. 获取注解的属性,用于后面的排除
    2. 获取所有需要自动装配的配置类的路径:这一步是最关键的,从 META-INF/spring.factories 获取自动配置类的路径
    3. 去掉重复的配置类和需要排除的重复类,把需要自动加载的配置类的路径存储起来
    protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            //1.获取到注解的属性
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            //2.获取需要自动装配的所有配置类,读取META-INF/spring.factories,获取自动配置类路径
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            //3.1.移除重复的配置
            configurations = this.removeDuplicates(configurations);
            //3.2.处理需要排除的配置
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.getConfigurationClassFilter().filter(configurations);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
        }
    }

标签: java, Java面试题, Java问题合集, Java编程, Java问题精选, Java常见问题