springboot自动装配原理(springboot知识点梳理二)
SpringBoot 3.x时代已经到来,这篇文章主要围绕还是2.7.x以下的版本作为记录。如有不正确的地方,望大佬们指正。
一、简述
springboot的的简述和启动流程都已经在(springboot(2.6.1版本)启动流程(springboot知识点梳理一)_onapplicationevent方法怎么启动-CSDN博客)文章中有进行记录,所以这里就不在进行记录了。这里主要记录一下自动装配原理。
二、什么是自动装配
相对于传统的spring项目,springboot它不需要繁琐的配置,这主要归功于springboot的自动装配机制来实现的。例如,以前的spring需要配置数据源,事务等等,但是springboot在启动过程中,会自动完成这些配置,这使我们减少了开发难度和成本,更加注重业务的实现。
三、自动装配流程
- 在springboot项目中有一个注解@SpringbootApplication,这个注解是对@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan这三个注解进行了封装,其中@EnableAutoConfiguration是实现自动化配置的核心注解。
- 该注解有两个核心注解,一个是@AutoConfigurationPackage(自动化配置包),主要作用是扫描该包下面的所有组件,一个是@Import导入的AutoConfigurationImportSelector类,所谓的自动装配都是通过@Import注解中的AutoConfigurationImportSelector实现的。
- 这个类实现了一个导入器接口ImportSelector。该接口中存在一个方法selectImports,该方法的返回值是一个数组,数组中存储的就是要被导入到spring容器中的类全类名。
- 在AutoConfigurationImportSelector类中重写了selectImport方法,该方法内部就是读取了项目的classpath路径下的META-INF/spring-factories文件中的所配置的类的全类名
- 在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到spring容器中
四、自动装配源码解析
自动装配主要是通过@springbootApplication注解是的@EnableAutoConfiguration注解来实现的,所以这篇文章也主要是围绕着它来进行记录。
4.1 @EnableAutoConfiguration源码
AutoConfigurationImportSelector会先执行,所以我们先了解它
4.2 @Import({AutoConfigurationImportSelector.class})的AutoConfigurationImportSelector类源码
4.3 批量导入getAutoConfigrationEntry源码
这个地方会进行过滤,不会把所有扫描的组件都进行加载,会根据条件来决定是否导入到spring容器中
4.4 加载MATE-INF/spring.factories的getCandidateConfigurations方法源码
继续了解组件注册
4.5 查看@AutoConfigurationPackage(自动化配置包)选择器
4.6 Registrar类源码
注意点
@AutoConfigurationPackage和@ComponentScan一样,也是将主配置类所在的包以及子包里面的组件扫描到IOC容器中,但区别是@AutoConfigurationPackage扫描@Enitity,@MapperSacn等第三方依赖注解,而@ComponentScan只扫描@Controller,@Service,@Component,@Repository这些常见注解,所以这两个扫描对象是不一样的
五、总结
springboot自动装配主要是通过spring-boot-autoconfigure包来实现,通过这个包springboot会在底层配好所有的组件。但是如果用户自己配置了,那么就以用户优先。
5.1 自动装配为什么不一次性全部加到容器中
如果spring中没有添加任何附加条件,此时的这些配置类中所定义的bean都会被导入到spring容器中,这样非常消耗内存,因此spring中提供了很多条件注解,通过这些条件注解控制某个配置是否有效
5.2 简单总结
在项目启动过程中,springboot框架会自动读取META-INF/spring.factories配置文件中的org.springbootframework.boot.autoconfigure.EnableAutoConfiguration所配置的配置类,然后将其中所定义的bean根据条件注解所指定的条件来决定是否需要将其导入到spring容器中
六、通过一张图来简单了解流程
参考文档:https://juejin.cn/post/7245170503798734904