SpringBoot自动装配原理解析(分析源码)

我们知道SpringBoot中底层帮我们做了很多事情,但是只会用是远远不够的,我们还需要对它的内部实现原理进行一定的了解,知其然并且知其所以然,才能在工作和学习中游刃有余

本文是笔者通过阅读源码和看视频所总结出来的,将从最初的主启动类开始分析,如有差错,欢迎文明讨论
笔者所使用SpringBoot版本为2.5.3,版本不同,源码可能会有细节上的不同

我们在创建一个SpringBoot项目时,IDEA会自动生成一个SpringBoot的启动类。如下图:

在这里插入图片描述

而这其中的注解@SpringBootApplication也是原理所在,它是一个组合注解,点进去如下图:
在这里插入图片描述

除了常规注解之外,我们发现它还被@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan三个注解标注,这也是接下来需要重点了解的三个注解

我们将重头戏放到后面,先分析不那么复杂的注解

  1. 首先刨析@ComponentScan,以下是@Component的源码解释

在这里插入图片描述
翻译过来:将@Configuration注解标注的类配置组件扫描指令,提供和Spring的XML文件中<context:component-scan>平行的支持(即意义等同于它)
说人话就是表示自动扫描主启动类同包和子包下的组件和bean,并将其加载到SpringIOC容器中。

  1. 接下来再看@SpringBootConfiguration注解,点进去如下图:

在这里插入图片描述

将上面的英文注解翻译过来,大概意思就是它是一个SpringBoot配置类,应用程序应该只包含一个@SpringBootConfiguration,大多数惯用的SpringBoot应用程序将从@SpringBootApplication继承它
说白了就一句话,这是一个SpringBoot的配置类
他被@Configuration标注,进入它:
在这里插入图片描述

我们发现它被@Component注解标注,因此从这里我们可以知道一个SpringBoot应用程序本质上还是一个Spring组件

  1. 最后也是最重要的一个注解@EnableAutoConfiguration,它是自动配置的核心注解,点进该注解:

在这里插入图片描述

这个注解表示开启自动配置,它主要被@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)两个注解标注,首先分析@AutoConfigurationPackage,进入该注解
在这里插入图片描述
该注解用来自动注册包,可以看到其中有一个@Import注解导入了一个AutoConfigurationPackages.Registrar.class,它用来注册包,这里和前面我们说的扫描包是连起来的,扫描过的包在这里注册!

返回到上一级, 我们分析另一个@Import(AutoConfigurationImportSelector.class)它导入了一个类AutoConfigurationImportSelector,这个类是自动配置的核心类,进入该类的主要方法:

在这里插入图片描述

getAutoConfigurationEntry()该方法用来获取自动配置属性,其中调用了一个同级方法如下:
在这里插入图片描述

getCandidateConfigurations()用来获取并返回候选配置,可以看到候选配置的获取是通过调用SpringFactoriesLoader类的一个静态方法loadFactoryNames()实现的,并且传入了一个方法getSpringFactoriesLoaderFactoryClass(),它用来获取加载配置类的工厂类,进入该方法:
在这里插入图片描述
可以看到返回的是@EnableAutoConfiguration注解标注的类!想想我们刚才走过来的路,这个被标注的类不就是启动类?所以说绕了一大圈我们发现,最终其实是让SpringBoot的主启动类来加载我们的所有候选配置类
返回到刚才的loadFactoryNames方法,进入它:
在这里插入图片描述

我们发现,loadFactoryNames()返回一个List集合,存放了需要加载的自动配置类的全限定名,Spring会根据这些全限定名来讲对应的配置类注册到IOC容器中,它调用了同级的loadSpringFactories方法,通过传入的类加载器(这个类加载器实际上也就是SpringBoot的启动类加载器)来加载了一个常量路径FACTORIES_RESOURCE_LOCATION,点进去:
在这里插入图片描述

发现该路径指向META-INF/spring.factories,它表示加载所有jar包中META-INFO下的spring.factories文件,而spring-boot-autoconfigure.jar包下存在该路径和该文件,并将他们封装成了Properties类型文件。

也就是说,SpringBoot启动时将会加载所有META-INF下的spring.factories的自动配置类,但到这里并没有结束。

进入该文件我们会发现他们都是以XXXAutoConfiguration来结尾的,表明他们是自动配置类,我们以HttpEncodingAutoConfiguration为例,点进去,会发现该类被注解@EnableConfigurationProperties标注
在这里插入图片描述

一旦自动配置类生效,这个注解表示会将该XXXProperties类和一个配置文件相绑定,也就是说该Properties类中的属性会和配置文件中的一一对应,我们可以通过配置文件设置Properties类中对应属性的值,注意名字不能写错。

而自动配置类生效也是需要条件的,我们可以看到上面例子中的配置类被一些@ConditionalOnXXX注解标注,这类注解叫做条件注解,如@ConditionalOnWebApplication表示当前要为web环境等等,只有这些条件注解的条件都满足了,这个自动配置类才能真正生效!
走到这里,SpringBoot的自动装配过程才算完成

下面是一些常用条件注解的作用:
@ConditionalOnJava:系统Java版本是否符合要求
@ConditionalOnBean:容器存在指定Bean
@ConditionalOnMissingBean:容器中不存在指定Bean
@ConditionalOnClass:类路径中存在指定class
@ConditionalOnMissingClass:类路径中不存在指定class
@ConditionalOnExpression:满足SpEL表达式指定
@ConditionalOnSingleCandidate:容器中只有一个指定的Bean,或者这个Bean是首选Bean
@ConditionalOnProperty:检查指定属性是否有指定值
@ConditionalOnResource:类路径下是否存在指定资源
@ConditionalOnWebApplication:当前应用是一个web应用环境
@ConditionalOnNotWebApplication:当前应用不是一个web应用环境
@ConditionalOnJndi:JNDI存在指定项


以上内容均是笔者通过阅读源码以及看视频资料所总结出来的,一些地方可能还不够细致,如有错误,欢迎文明讨论

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值