Rubin's Blog

  • 首页
  • 关于作者
  • 隐私政策
享受恬静与美好~~~
分享生活的点点滴滴~~~
  1. 首页
  2. SpringBoot
  3. 正文

SpringBoot之自动装配原理

2021年 8月 30日 1345点热度 1人点赞 2条评论

前言

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文件中的配置类加载并经过去重和两次过滤(手动指定排除类过滤和条件过滤)之后注入我们的容器中。通过以上两步,完成了我们的自动装配。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: SpringBoot
最后更新:2022年 6月 9日

RubinChu

一个快乐的小逗比~~~

打赏 点赞
< 上一篇
下一篇 >

文章评论

  • 一只一一

    老板文章不错,支持一波,加油加油,继续出系列,追更哟,求更求更 :eek:

    2021年 8月 30日
    回复
    • RubinChu

      @一只一一 好嘞 :rolleyes:

      2021年 8月 30日
      回复
  • razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
    取消回复
    文章目录
    • 前言
    • 自动装配
      • 自动装配的原理以及流程
      • 自动装配实现步骤
    • 总结
    最新 热点 随机
    最新 热点 随机
    问题记录之Chrome设置屏蔽Https禁止调用Http行为 问题记录之Mac设置软链接 问题记录之JDK8连接MySQL数据库失败 面试系列之自我介绍 面试总结 算法思维
    Redis之Codis集群搭建 Kafka高级特性之消费者 MySQL学习之字符串类型 MyBatis之复杂映射开发 SpringBoot之缓存 MySQL之Sharding-JDBC分布式事务

    COPYRIGHT © 2021 rubinchu.com. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang

    京ICP备19039146号-1