SpringBoot 自动配置原理

1. @SpringBootApplication源码

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

    @AliasFor(annotation = EnableAutoConfiguration.class)
    Class<?>[] exclude() default {};

    @AliasFor(annotation = EnableAutoConfiguration.class)
    String[] excludeName() default {};

    @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
    String[] scanBasePackages() default {};

    @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
    Class<?>[] scanBasePackageClasses() default {};

    @AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

    @AliasFor(annotation = Configuration.class)
    boolean proxyBeanMethods() default true;

}

@SpringBootApplication@SpringBootConfiguration@EnableAutoConfiguration @ComponentScan

@SpringBootConfiguration@SpringBootConfiguration 相当于 @Configuration
@EnableAutoConfiguration开启自动配置
@ComponentScan符合条件的类会被扫描、解析成 BeanDefinition,进而被实例化成 bean

2. @EnableAutoConfiguration 源码解析

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

	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

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

	String[] excludeName() default {};

}

2.1 @Import 注解

@Import 注解注入的类一般有以下特征:

实现 ImportSelector 接口会在解析阶段执行 selectImports 方法,方法返回的类名数组,会被解析成 BeanDefinition 对象,进而被实例化成 bean
实现 ImportBeanDefinitionRegistrar 接口会在解析阶段执行 registerBeanDefinitions 方法,一般会注册 BeanDefinition 对象
配置类以配置类进行解析

2.2 AutoConfigurationImportSelector 源码

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
		ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
}
2.2.1 AutoConfigurationImportSelector 类继承关系

AutoConfigurationImportSelector 实现 DeferredImportSelector 接口,DeferredImportSelector 继承 ImportSelector 接口,所以 AutoConfigurationImportSelector 满足 DeferredImportSelector 和 ImportSelector(2.1) 的特性

2.2.1.1 DeferredImportSelector 特性

ConfigurationClassParser#parse

DeferredImportSelector 的处理滞后于普通配置类 (一般会依赖普通配置类的解析结果,所以解析时机靠后 )

2.2.2 AutoConfigurationImportSelector#selectImports
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    }
    AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
    return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
2.2.2.1 AutoConfigurationImportSelector#isEnabled
protected boolean isEnabled(AnnotationMetadata metadata) {
    if (getClass() == AutoConfigurationImportSelector.class) {
        return getEnvironment().getProperty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true);
    }
    return true;
}
  • @Import 导入的类是否为 AutoConfigurationImportSelector
    • 是:属性 ENABLED_OVERRIDE_PROPERTY 的值(默认 true)
    • 否:true
2.2.2.2 AutoConfigurationImportSelector#getAutoConfigurationEntry
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
        return EMPTY_ENTRY;
    }
    AnnotationAttributes attributes = getAttributes(annotationMetadata);
    List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
    configurations = removeDuplicates(configurations);
    Set<String> exclusions = getExclusions(annotationMetadata, attributes);
    checkExcludedClasses(configurations, exclusions);
    configurations.removeAll(exclusions);
    configurations = getConfigurationClassFilter().filter(configurations);
    fireAutoConfigurationImportEvents(configurations, exclusions);
    return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
2.2.2.2.1 AutoConfigurationImportSelector#getAttributes 

获取 @EnableAutoConfiguration 注解属性(exclude、excludeName)

2.2.2.2.2 AutoConfigurationImportSelector#getCandidateConfigurations

getCandidateConfigurations 方法会加载文件 META-INF/spring.factories,找到 key 为 EnableAutoConfiguration 对应的 value

2.2.2.2.3 AutoConfigurationImportSelector#removeDuplicates

去除重复值

2.2.2.2.4 AutoConfigurationImportSelector#getExcludeAutoConfigurationsProperty
  • @EnableAutoConfiguration 配置的 excludeexcludeName 属性的值
  • 属性 spring.autoconfigure.exclude 的值
2.2.2.2.5 AutoConfigurationImportSelector#checkExcludedClasses

如果 2.2.2.2.4 配置的相关 Class 存在,且 2.2.2.2.2 (getCandidateConfigurations)获取的自动配置类不存在,则抛出异常

2.2.2.2.6 AutoConfigurationImportSelector#getConfigurationClassFilter

一共有三个 filters,filters 明细如下:

  • OnBeanCondition
  • OnClassCondition
  • OnWebApplicationCondition

ConfigurationClassFilter 的构造方法

构造方法小结

ConfigurationClassFilter 的构造方法会加载文件 META-INF/spring-autoconfigure-metadata.properties,该文件记录了自动配置类可以被加载需要满足的前置条件。默认情况下,待加载的自动配置类,满足相应 filters 的 (OnBeanCondition、OnClassCondition、OnWebApplicationCondition)match 方法就可以被加载

2.2.2.2.7 AutoConfigurationImportSelector#fireAutoConfigurationImportEvents

Listeners 发送 AutoConfigurationImportEvent 事件

2.2.2.2.8 AutoConfigurationImportSelector#selectImports 小结

AutoConfigurationImportSelector 的 selectImports 方法会返回 String 数组,在后期会被解析成 BeanDifinition,进而实例化成 bean

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值