Springboot自动配置原理+面试回答

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 理解springboot自动装配首先要理解什么是约定优于配置,它的设计目的是用来简化spring应用的初始化搭建以及开发过程,从而使开发人员不在需要定义样板化的配置,按照约定进行编程,是一种软件设计范式

springboot自动配置面试相关内容在文章最后,小伙伴根据选择观看哦

前言:理解springboot自动装配首先要理解什么是约定优于配置,它的设计目的是用来简化spring应用的初始化搭建以及开发过程,从而使开发人员不在需要定义样板化的配置,按照约定进行编程,是一种软件设计范式

首先springboot整合的每一个技术点都会对应着两个类一个是XXXProperties,另一个是XXXAutoConfiguration

XXXAutoConfiguration:帮我们实例化一些组件

XXXProperties:在我们实例化的过程中可能需要一些值,那么就在这个类里给他赋值

拿Mybatis来说,我们只需要导入mybatis的starter在经过简单的配置就可以使用了,

我们可以搜索一个类叫MybatisProperties,这里是springboot帮我们注入属性值,也就是依赖注入,而我们只需要配置必要的信息就可以使用,是因为springboot采用约定大于配置,我们只需要去修改我们需要的那一部分就可以了

然后在看到MybatisAutoConfiguration,首先他有一个注解@Configuration所以他是一个配置类,这个类的主要作用就是帮我们实例化一些组件

在这个文件里都是springboot主动整合的第三方技术所对应的XXXAutoConfiguration类,也就是这个类的全限定名, 然后通过反射的原理就是class.forname来新建这个对象

接下我们来看怎么读到这个这个文件,这个时候来看到主启动类的核心注解:

而核心的注解分别是

@SpringBootConfiguration

@EnableAutoConfiguration

@ComponentScan

对于@ComponentScan这个注解还是比较核心的,需要重点理解一下,它是来自于spring框架的一个注解,作用是对指定的package进行扫描,找到其中符合条件的类,默认是搜索被@Component所修饰的配置类,也可以通过指定属性来指定要进行扫描的package,也就是扫描我们的controller等,而他是怎么扫描到的呢,就是根据我们的@EnableAutoConfiguration注解,这个注解点进去有一个@AutoConfigurationPackage

这个继续点进去有一个注册器Registrar

通过这个注册器我们就可以找到当前类所在的包

现在来看一下在MET-INF下的spring.factories是怎么加载的,现在我们还是看到@EnableAutoConfiguration这个注解,这个注解下又导入了一个类@Import({AutoConfigurationImportSelector.class})

简单理解一下@Import:是来自spring框架的一个注解,作用是显示的从其他地方加载配置类的方式,这样可以避免使用性能较差的组件进行扫描

然后继续来看AutoConfigurationImportSelector.class的作用,这个翻译过来的意思为自动配置导入选择器

我们都知道,如果这个类实现了ImportSelector接口,那他肯定重写了一个方法就是selectImports方法,而在这个类里也不例外,这个类里确实有这个方法

他通过getAutoConfigurationEntry来进行导入,我们继续点进去

而这个getCandidateConfigurations方法的返回值是string,而这个方法就是真正帮我们去读到那个spring.factories配置文件

这个集合真正读取到了我们spring.factories所有的自动配置类,而这里面也默认加载了redis的内容,既然加载了redis我们又没导包,那他为什么不报错呢

这个取决于@ConditionalOnClass,这个注解通俗的说就是Spring工程中引用了redis的包 才会构建这个bean,就是说只有在classpath下能找到redisTemplate类才会构建这个bean。

简单理解,加了这个注解的类不一定会生效,只有这个注解里面指定的那个类存在,那么他才会生效,如果不存在那么这个类就不生效,也就是说我们刚刚在getCandidateConfigurations读取到的130多个配置类并没有全部被加载,只是加载了我们引入了依赖的类

因此我们的redistemplate就不需要我们自己new对象了,而是通过ioc控制反转进行外部注入,而stringRedisTemplate是经过序列化后的对象,因为不序列化默认走的是JDK的序列化器,那样存入redis的结果不仅占用内存较高而且不容易阅读

在这里我们就可以发现只要我们导了redis的启动器,我们就不需要配太多的东西就可以使用了

在RedisProperties这个类里,就是我们常用的配置,而默认的host地址是localhost,因此我们只要windows本地启动了redis,我们不需要任何配置文件,就可以使用redis,这样就基本完成我们的自动装配了

继续看回来springboot拿到我们从spring.factories读取的这个集合后到 ImportAutoConfigurationImportSelector的determineImports方法,然后在这里又把这个集合包装成一个set集合,作用是为了去重

然后在这通过各种校验过滤

最后返回一个AutoConfigurationEntry

在这里就是通过@ConditionalOnClass来进行排除过滤

再到这个方法内,他利用String工具类转成一个数组,返回给spring容器,然后再利用类加载器,通过Class.fornaame也就是通过反射的方式帮我们实例化,实例化完成之后帮我们放到IOC容器里

简单来讲:就是通过springboot的核心注解里的选择器,而这个选择器会加载我们的spring.factories文件,拿到这些文件之后通过反射生成对象,在反射生成的时候要先判断我们有没有导包,如果没导包就不生成,导包了就生成,然后通过XXXProperties给属性赋值,没有的我们就需要在yml中自己配置

面试话术:

主配置类启动,通过@SringBootApplication 中的@EnableAutoConfguration 加载所需的所 有自动配置类,然后自动配置类生效并给容器添加各种组件。那么@EnableAutoConfguration 其实是通过它里面的@AutoConfigurationPackage 注解,将主配置类的所在包皮下面所有子包 里面的所有组件扫描加载到 Spring 容器中; 还通过@EnableAutoConfguration 里面的 AutoConfigurationImportSelector 选择器中的 SringFactoriesLoader.loadFactoryNames()方法,获取类路径下的 META-INF/spring.factories 中的 资源并经过一些列判断之后作为自动配置类生效到容器中,自动配置类生效后帮我们进行自 动配置工作,就会给容器中添加各种组件:这些组件的属性是从对应的 Properties 类中获取 的,这些 Properties 类里面的属性又是通过@ConfigurationProperties 和配置文件绑定的:所以 我们能配置的属性也都是来源于这个功能的 Properties 类。SpringBoot 在自动配置很多组件 的时候,先判断容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置 的,如果没有,才自动配置;如果有些组件可以有多个就将用户配置和默认配置的组合起来

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
24天前
|
NoSQL Java 测试技术
字节二面:Spring Boot Redis 可重入分布式锁实现原理?
字节二面:Spring Boot Redis 可重入分布式锁实现原理?
106 0
|
24天前
|
消息中间件 存储 安全
RabbiMQ原理与SpringBoot使用
RabbiMQ原理与SpringBoot使用
34 0
|
2天前
|
缓存 Java Maven
Spring Boot自动配置原理
Spring Boot自动配置原理
11 0
|
23天前
|
缓存 Java uml
SpringBoot2 | Spring AOP 原理深度源码分析(八)
SpringBoot2 | Spring AOP 原理深度源码分析(八)
31 0
|
23天前
|
存储 Java Spring
SpringBoot2 | 条件注解 @ConditionalOnBean 原理源码分析(七)
SpringBoot2 | 条件注解 @ConditionalOnBean 原理源码分析(七)
13 0
|
23天前
|
存储 关系型数据库 MySQL
面试题15: Mysql 数据存储原理
面试题15: Mysql 数据存储原理
|
24天前
|
Java 编译器 API
【面试问题】注解的实现原理?
【1月更文挑战第27天】【面试问题】注解的实现原理?
|
25天前
|
Java Spring
SPRINGBOOT启动原理(基于3.x版本)(三)- SpringApplication里有啥
SPRINGBOOT启动原理(基于3.x版本)(三)- SpringApplication里有啥
19 0
|
26天前
|
消息中间件 Java Linux
面试官:说一下零拷贝技术的实现原理?
面试官:说一下零拷贝技术的实现原理?
459 2
面试官:说一下零拷贝技术的实现原理?
|
1月前
|
存储 安全 网络协议
面试必备基本知识HTTPS 原理分析
面试必备基本知识HTTPS 原理分析

相关产品

  • 云迁移中心