SpringBoot自动配置原理

SpringBoot自动配置原理

在了解SpringBoot自动配置原理前,我们得先了解SpringBoot的启动类注解@SpringBootApplication,该注解是一个复合注解。

在这里插入图片描述

点进去可以发现,其本身依赖了很多注解,而SpringBoot自动配置的关键性注解是@EnableAutoConfiguration,但其实这个注解也是一个复合注解,用于载入所有应用程序需要导入的默认配置。当然,@SpringBootConfiguration和@ComponentScan也是自动配置中比较重要的注解。

  1. @SpringBootConfiguration:底层是@Configuration,也就是说其本身是支持JavaConfig的方式进行配置,可以理解为Configuration配置类等同于XML文件。
    在这里插入图片描述
    在这里插入图片描述
  2. @ComponentScan:扫描注解,说成事务大家也好理解,主要用来扫描当前类下的package,也就是将@Controller、@Service、@Component、@Repository等标记的加载到IOC容器中。

在这里插入图片描述

点进来就可以看到SpringBoot自动配置最重要的两个注解:

  1. @AutoConfigurationPackage:自动配置包
  2. @Import(AutoConfigurationImportSelector.class)

在这里插入图片描述

EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY是什么?这里我们可以先猜测成一个资源配置文件。
在这里插入图片描述

一、@AutoConfigurationPackage

在这里插入图片描述

这个知道它是自动配置包就行,点进去我们可以发现,它本身还是依赖于@Import,点进AutoConfigurationPackages.Registrar.class我们可以发现,其内部是重写了registerBeanDefinitions(…)方法,并调用了register方法来注册Bean。
在这里插入图片描述
了解:register(…)方法中,在注册bean时,先对bean进行查找,registry.containsBeanDefinition(BEAN)返回的是一个boolean值,如果为true时,就说明bean已经存在,在注册时需要添加索引;如果为false,bean就不存在,这是我们就可以注册一个bean。
在这里插入图片描述

二、@Import(AutoConfigurationImportSelector.class)

这个注解可以说才是真正的SpringBoot自动配置的核心奥义。首先我们点进去看一下源码,看不懂英文的话也没什么,可以百度翻译,但一些关键词还是得懂的,像什么Auto、Configuration啥的,回到源码我们可以看到AutoConfigurationImportSelector类实现DeferredImportSelector接口
在这里插入图片描述
然后我们可以点进该接口看一下,这个接口又继承ImportSelector类,
在这里插入图片描述
点进这个类我们可以发现,其调用了selectImports()方法,也就是实现自动配置的一个核心方法。
在这里插入图片描述
我们可以看到它里边调用了一个叫isEnabled()的方法,isEnabled()方法用来判断SpringBoot是否开启了自动配置。若开启就通过getAutoConfigurationEntry()来获取需要配置的Bean全限定名数组,否则就直接返回空数组。
在这里插入图片描述

getAutoConfigurationEntry()方法,用来获取需要自动配置的bean信息。

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
   if (!isEnabled(annotationMetadata)) {
      return EMPTY_ENTRY;
   }
   // 获取@EnableAutoConfiguration注解的属性
   AnnotationAttributes attributes = getAttributes(annotationMetadata);
   // 从spring.factories文件中获取配置类的全限定名数组
   List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
   // 去重
   configurations = removeDuplicates(configurations);
   // 获取注解中exclude或excludeName排除的类集合
   Set<String> exclusions = getExclusions(annotationMetadata, attributes);
   // 检查被排除类是否可以实例化,是否被自动配置所使用,否则抛出异常
   checkExcludedClasses(configurations, exclusions);
   // 去除被排除的类
   configurations.removeAll(exclusions);
   // 使用spring.factories配置文件中配置的过滤器对自动配置类进行过滤
   configurations = getConfigurationClassFilter().filter(configurations);
   // 抛出事件
   fireAutoConfigurationImportEvents(configurations, exclusions);
   return new AutoConfigurationEntry(configurations, exclusions);
}

getAttributes():获取@EnableAutoConfiguration注解属性
在这里插入图片描述

getCandidateConfigurations():从spring.factories文件获取需要配置的bean。
在这里插入图片描述
getCandidateConfigurations()方法通过SpringFactoriesLoader的loadFactoryNames()方法从所有的spring.factories文件中获取需要配置的bean全限定名列表。
在这里插入图片描述
打开spring.factories , 看到了很多自动配置的文件;这就是自动配置根源所在。
所以,自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件 ,并将其中对应的 org.springframework.boot.autoconfigure. 包下的配置项,通过反射实例化为对应标注了@Configuration的JavaConfig形式的IOC容器配置类 ,然后将这些都汇总成为一个实例并加载到IOC容器中。

注意:SpringBoot 2.X和SpringBoot 3.X自动装配是有区别的

springboot2.x和springboot3.x的版本的约定位置是不一致的。

在SpringBoot 2.X中:
  约定配置是META-INF下面的的spring.factories 文件中

在SpringBoot 3.X中:
  约定配置是META-INF下面的spring文件夹下的org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中

最后我们可以启动类时debug一下。找到beanFactory,然后找到下面这个在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值