SpringBoot自动配置原理

自动装配,简单来说就是自动把第三方组件的 Bean 装载到 Spring IOC 器里面,不需要开发人员再去写 Bean 的装配配置。在 Spring Boot启动类加上@SpringBootApplication 注解就可以实现自动装配。@SpringBootApplication 是一个复合注解,真正实现自动装配的注解是@EnableAutoConfiguration。

@SpringBootApplication
@ComponentScan(basePackages = {"com...."})
public class SmartApplication {
	public static void main(String[] args) {
		SpringApplication.run(SmartApplication.class, args);
	}
}

在这里插入图片描述
@EnableAutoConfiguration也是一个复合注解,内部@import注解引入了一个AutoConfigurationImportSelector 自动配置类选择器。
ps:@SpringbootConfiguration 是 Spring Boot 提供的一个注解,继承了 @Configuration 的功能,可以理解等同于@Configuration。
@ComponentScan自动扫描并加载符合条件的Bean。其实,如果启动类中不需要增加配置内容,也不需要指定扫描路径,可以使用@EnableAutoConfiguration来替代@SpringBootApplication,也可以完成启动。

@AutoConfigurationPackage // 指定扫描的基础包,SpringBoot将会扫描该包及其子包中的所有类,以查找和加载自动配置类和其他组件
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    Class<?>[] exclude() default {};

    String[] excludeName() default {};
}

AutoConfigurationImportSelector类中实现了ImportSelector接口,并重写了其selectImports方法。

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

getAutoConfigurationEntry方法中调用了一个关键方法:getCandidateConfigurations,获取所有候选配置信息。

//可以先看下获取的大致流程,而后进入查看器方法内部的具体实现
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
	//1.  从注解元数据中获取注解的相应属性,将相应属性存储到map中返回
  	//1.1 AnnotationAttributes是一个Map集合,其继承了LinkedHashMap
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
  	//2. 获取自动配置候选项
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
	//2.1 通过removeDuplicates()方法对自动配置的类名进行去重处理
  configurations = removeDuplicates(configurations);
  	//3. 根据注解元数据和注解属性获取到需排除配置项
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
  	//3.1检查是否有无效的排除类存在
		checkExcludedClasses(configurations, exclusions);
  	//3.2从自动配置候选项中删除需要排除的配置项 
		configurations.removeAll(exclusions);
  	//4. 调用getConfigurationClassFilter()方法获取到获取配置的所有AutoConfigurationImportFilter的实现类(对spring.factories进行过滤的类),调用filter方法对配置文件进行筛选,而后返回需要自动配置的类
		configurations = getConfigurationClassFilter().filter(configurations);
  	//5. 根据spring.factories文件中的AutoConfigurationImportListener事件监听器发布并处理监听事件,最后根据多次过滤、判重返回配置类合集
		fireAutoConfigurationImportEvents(configurations, exclusions);
  	//6. 创建一个新的配置实体ConfigurationEntry并返回,包含需要配置项configurations,和被排除配置项exclusions
		return new AutoConfigurationEntry(configurations, exclusions);
	}

点开getCandidateConfigurations方法,源代码如下:

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

SpringFactoriesLoader会加载META-INF/spring.factories文件,该文件以键值方式存储,将EnableAutoConfiguration下的所有配置类装载到容器中去。
在这里插入图片描述
如getAutoConfigurationEntry方法的源代码,在getCandidateConfigurations执行后,进行去重、排除、过滤等操作。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值