前言
SpringBoot作为当前比较流行的基础框架,其特征以及原理在面试中经常被问到。这篇博文主要阐述了SpringBoot关于自动装配的原理,来作为笔者学习路上的记录,也可以给想了解的小伙伴一个参考。
自动装配
首先,我来解释一下什么是自动装配。自动装配就是说我们只需要引入组件的相关依赖,SpringBoot框架会自动为我们装配相应的工具到Spring容器中。比方说,我们引入了redis的starter依赖,默认情况下,一个RedisTemplate类型的组件框架会给我们自动装配好并注入到Spring容器中。
了解完自动装配的概念,我们会有这样的疑问:SpringBoot是怎么样实现这种自动装配机制的呢?下面,我们就结合一个面试题的答题技巧来展开自动装配的原理介绍。
关于“什么是SpringBoot自动装配”类型的面试题,我们一定要注意:不要从SpringBoot的启动类来展开阐述!而是要从自动装配的原理来展开阐述。
自动装配的原理以及流程
我们可以首先解释一下自动装配,然后解释自动装配的默认配置类都配置在了classpath下的spring.factories文件里面。我们可以参考源码中的spring-boot-autoconfigure
模块的spring.factories文件,如下图所示:

该文件中配置了很多需要自动加载的类,这些类中以Enable
开头的便是自动装配的类,我们打开RabbitAutoConfiguration
配置类看一下:

我们可以看到该类上有条件注解,也就是以@Condition
开头的注解。也就是说,在项目启动时,SpringBoot会按照条件过滤需要自动装配的配置类。这样的话,我们自动装配的总体流程就清楚了,也就是:项目启动扫描classpath下所有的spring.factories文件并加载文件中的类-根据条件过滤配置类-将符合条件的配置类加载进容器中。
自动装配实现步骤
解释完自动装配的流程之后,我们再切回到SpringBoot的Main方法,开始讲解SpringBoot实现自动装配的逻辑。
在启动类上,我们都会看到这样一个注解:@SpringBootApplication
。我们打开源码看一下这个注解的定义信息:

上图我们可以看到,这是一个组合注解。我们重点关注@EnableAutoConfiguration
注解:

可以看到,这也是一个组合注解。我们先打开该注解上的@AutoConfigurationPackage
注解的源码看一眼:

我们可以看到,该注解导入了一个配置类:AutoConfigurationPackages.Registrar
,我们查看一下该类的源码:

我们可以看到,该配置类实现了ImportBeanDefinitionRegistrar
接口,而ImportBeanDefinitionRegistrar
接口的实现类只要定义在了配置类的@Import
注解的values数组里面,容器在启动中的某一个时机(容器初始化BeanFactory之后触发BeanFactoryPostProcessor
的时候,中间过程太多,有兴趣的小伙伴可以跟踪一下)会调用该实现类的registerBeanDefinitions
方法来注册一个自定义的的BeanDefinition到容器中。我们点击register
方法:

由上图可以,该方法向容器注册了一个类型是org.springframework.boot.autoconfigure.AutoConfigurationPackages
的bean。并将包扫描路径封装进了该bean。该路径的作用,根据该bean的文档解释是为了关联组件(比如说JPA
的EntityScanner
会使用)的后续使用。
解释完第一个注解之后,我们在来看看第二个导入的配置类:AutoConfigurationImportSelector
。该类有一个内部类org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup
。在我们的容器创建完成,执行所有 BeanFactoryPostProcessor
的时候会调用其process
方法,该方法如下图所示:

上图中比较重要的方法有两个,第一个是getAutoConfigurationMetadata
(方法主要是读取配置文件来获取SpringBoot的一些过滤器实例,也就是以@OnCondition
为前缀的注解校验器等等自动装配过滤器)和getAutoConfigurationEntry
。getAutoConfigurationEntry
方法如下:

上图中可以看到该方法的步骤逻辑:获取注解的描述实体 -> 加载自动装配的配置类(即加载classpath下面的所有spring.factories文件中配置的配置类)-> 去除重复的配置类 -> 去除我们指定的配置类 -> 根据我们第一步加载的校验器来校验该配置类是否符合加载条件,去除校验失败的配置类 -> 发布自动配置导入事件 -> 将过滤之后的自动配置类封装返回。
每一步的具体细节这里就不一一赘述了,有兴趣的小伙伴可以自己查看一下源码。总的来讲,这一步就是加载所有配置在spring.factories文件中的配置类,并经过去重、去除指定排除类和校验器去除条件不允许的类,将符合条件的类注册进容器中。以此来完成我们的自动装配。
总结
我们来总结一下关于回答SpringBoot自动装配相关问题的流程:1、 先说一下SpringBoot自动装配是什么。自动装配是我们引入相关依赖之后,SpringBoot自动帮我们将对应组件按照约定的条件装配进容器中供我们使用,我们无需手动配置所需组件。2、 再来回答自动装配的实现逻辑。SpringBoot的启动类的@SpringBoorApplication
注解是一个组合注解,它标记了启动类是一个配置类,并导入了两个ImportSelector。这两个selector一个将本类的路径作为包基础路径封装进实体里面以供后续bean使用,一个将我们配置在spring.factories文件中的配置类加载并经过去重和两次过滤(手动指定排除类过滤和条件过滤)之后注入我们的容器中。通过以上两步,完成了我们的自动装配。
文章评论
老板文章不错,支持一波,加油加油,继续出系列,追更哟,求更求更
@一只一一 好嘞