【SpringBoot】SpringBoot源码解析第三章 SpringBoot的自动化配置

 fe6616eb4004c49e2d58a7bbd677f032.png

【SpringBoot】SpringBoot源码解析第一章 SpringBoot的构造方法-CSDN博客

【SpringBoot】SpringBoot源码解析第二章 SpringBoot的run方法-CSDN博客

【SpringBoot】SpringBoot源码解析第三章 SpringBoot的自动化配置-CSDN博客

【SpringBoot】SpringBoot源码解析第四章 SpringBoot的bean接口-CSDN博客

【SpringBoot】SpringBoot源码解析第五章 SpringBoot的beanDefinition收集过程-CSDN博客

【SpringBoot】SpringBoot源码解析第六章 SpringBoot的getBean方法-CSDN博客

【SpringBoot】SpringBoot源码解析第七章 SpringBoot的感悟-CSDN博客

上一章我们分析了SpringBoot对象的run方法,这一章我们来分析SpringBoot自动配置的实现原理

参考源码:<spring.boot.version>2.3.12.RELEASE</spring.boot.version>

目录

1、SpringBoot自动配置的实现原理

2、自动配置入口

2.1  selectImports什么时候才会被调用

2.2  没调用selectImports方法又是怎么实现自动配置的

3、总结

SpringBoot的设计理念之一是约定大于配置,其中约定指的是默认配置。在SpringBoot框架中使用默认配置即可快速搭建一个应用,这些默认配置如何自动生效就是本篇讨论的主题

1、SpringBoot自动配置的实现原理

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

SpringBoot的自动配置是通过@SpringBootApplication注解来实现的,点击进入@SpringBootApplication注解

9b3097548a6c4d5984b5478ecaa6c7dd.png

@SpringBootApplication内又嵌套了很多其他注解,其中和自动配置相关的是@EnableAutoConfiguration,点击进入

b6ccc2a56efd499dbcfb2cf9dafb23fb.png

@EnableAutoConfiguration使用@import注解往Spring容器内添加了一个AutoConfigurationImportSelector类,该类的selectImports方法会获取自动配置类的信息,点击进入

087ed3677f734646aec69bdfa8fdccdc.png

跟着selectImports方法走到loadSpringFactories方法

调用链:
-> selectImports
-> getAutoConfigurationEntry(annotationMetadata)
-> getCandidateConfigurations(annotationMetadata, attributes)
-> SpringFactoriesLoader.loadFactoryNames
-> loadSpringFactories(classLoader)

d8d9a3fad77e4da486ada2e274781319.png

loadSpringFactories方法会加载classpath目录下所有的META-INF/spring.factories文件,从文件中获取符合类型要求的类的全限定类名,这个方法我们在第一章SpringBoot对象的构造方法中就已经介绍过了

【SpringBoot】SpringBoot源码解析第一章 SpringBoot的构造方法-CSDN博客

到这里我们基本可以理清SpringBoot自动配置的原理:加载classpath目录下所有的META-INF/spring.factories文件,并且将其中符合自动化配置类要求的配置项通过java反射进行实例化,然后汇总并加载到Spring的容器

2、自动配置入口

如果在AutoConfigurationImportSelector的selectImports方法上debugger,会发现启动应用后不会走到这个方法,那么什么时候才会调用selectImports方法呢?如果没有调用selectImports方法,SpringBoot又是怎么实现自动配置的?我们逐个来解答

2.1  什么时候调用selectImports方法

c0271bb615cb44448ca0ffb1d8e2f706.png

AutoConfigurationImportSelector实现了DeferredImportSelector接口,DeferredImportSelector接口继承了ImportSelector接口,selectImports方法其实来自ImportSelector接口

应用启动到调用selectImports方法的过程如下

调用链:
-> ConfigurationClassParser.parse
-> this.parse(((AnnotatedBeanDefinition)bd).getMetadata(), holder.getBeanName());
-> processConfigurationClass
-> doProcessConfigurationClass(configClass, sourceClass, filter)
-> processImports
-> selectImports

b21a1bd5b36741edb4a45f45a74a2bb4.png

processImports方法处理@import注解时,如果选择器实现了DeferredImportSelector接口,就会调用延迟选择器的handle方法,将选择器包装成holder放到延迟选择器内,否则直接调用选择器的selectImports方法

也就是说因为AutoConfigurationImportSelector实现了DeferredImportSelector接口,所以启动应用是不会调用AutoConfigurationImportSelector的selectImports方法的,AutoConfigurationImportSelector的selectImports方法并没有触发的时机

2.2  没有调用selectImports方法,SpringBoot又是怎么实现自动配置的

根据2.1的分析我们可以得知AutoConfigurationImportSelector实现了DeferredImportSelector接口,会走延迟选择器的handle方法这个分支。后续会走到延迟选择器的process方法

8f81b1521061489599db1d143bf54a92.png

31b34cd5c1794e06898d4ef2a4dc4d66.png

AutoConfigurationImportSelector的process方法会调用getAutoConfigurationEntry方法,这个方法就是1中介绍的获取自动配置全限定名的方法,即使不走AutoConfigurationImportSelector的selectImports方法,也可以拿到自动配置的信息,接着调用AutoConfigurationGroup类的selectImports方法,AutoConfigurationGroup是AutoConfigurationImportSelector的一个内部类,两个类都有selectImports方法,但它们并不相同,需要区分开来

3、总结

SpringBoot应用启动后会扫描classpath目录下所有的META-INF/spring.factories文件,从文件中获取自动化配置的类并实例化

下一章我们分析Spring和bean相关的接口

【SpringBoot】SpringBoot源码解析第四章 SpringBoot的bean接口-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值