Spring Boot 自动装配原理
Spring Boot 自动装配原理
Spring Boot 在启动之前还有一系列的准备工作,比如:推断 web 应用类型,设置初始化器,设置监听器,启动各种监听器,准备环境,创建 applicationContext,准备 context 上下文对象,在 prepareContext 的时候,将 main 函数所在的类(也就是主类)通过 AnnotatedBeanDefinitionReader 注入到 IOC 中,然后 refreshContext 开始刷新,这里面会调用 AbstractApplicationContext.refresh() 方法。然后就开始了 Spring IOC 的一系列操作。而 Spring Boot 的自动装配就是在此处展开。
主要是在 ConfigurationClassPostProcessor 类中对其进行的处理,具体的解析逻辑参考07-Spring ConfigurationClassPostProcessor,这里只说一下在 Spring Boot 中的处理。
在 Spring Boot 中,ConfigurationClassPostProcessor 类的注入是在 createApplicationContext() 中进行的,AnnotationConfigServletWebServerApplicationContext 中的无参构造方法会在 AnnotatedBeanDefinitionReader 创建的时候调用 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); 将其注入进去。
实例化并且调用是在 AbstractApplicationContext 中进行的,最终会在 ConfigurationClassPostProcessor#processConfigBeanDefinitions 调用 ConfigurationClassParser#parse 的方法,最后会调用 doProcessConfigurationClass 对其各种注解进行解析,在处理 @Import 注解的时候会将 @Import 导入的类通过 getImports(sourceClass) 方法直接获得,可以看到 importCandidates 中有四个值,主要的两个为 AutoConfigurationPackages$Register 和 AutoConfigurationImportSelector,
通过类图可以看到 AutoConfigurationImportSelector 实现了 DeferredImportSelector 接口,所以在 processImports 中处理的时候,会使用 DeferredImportSelectorHandler#handle 进行处理,将其添加到 deferredImportSelectors 列表中,
解析完成之后,在 ConfigurationClassParser#parse 方法中 this.deferredImportSelectorHandler.process() 进行处理导入的 AutoConfigurationImportSelector类。使用 DeferredImportSelectorGroupingHandler#processGroupImports() 进行下一步的处理。
grouping.getImports() -> getImports() -> process()。
在 process 方法中会获取所有自动装配的 class 对象,调用的是 AutoConfigurationImportSelector#getAutoConfigurationEntry 的方法,通过getCandidateConfigurations(annotationMetadata, attributes) 获取所有的候选配置类,在其中调用 SpringFactoriesLoader#LoadFactoryNames 方法获取。
AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector)deferredImportSelector).getAutoConfigurationEntry(annotationMetadata);
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct.");
return configurations;
}
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
String factoryTypeName = factoryType.getName();
return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}
/** 返回SpringFactoriesLoader用来加载候选配置的类 */
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
最终通过 loadSpringFactories 获取在 META-INF/spring.factories 中所有的配置。
在 configurations = getConfigurationClassFilter().filter(configurations); 中将不符合条件的类过滤掉。
Spring Boot 自动装配原理的更多相关文章
- Spring Boot系列(二):Spring Boot自动装配原理解析
一.Spring Boot整合第三方组件(Redis为例) 1.加依赖 <!--redis--> <dependency> <groupId>org.springf ...
- 从源码中理解Spring Boot自动装配原理
个人博客:槿苏的知识铺 一.什么是自动装配 SpringBoot 定义了一套接口规范,这套规范规定:SpringBoot在启动时会扫描外部引用jar包中的META-INF/spring.factori ...
- Spring Boot 自动装配(二)
目录 目录 前言 1.起源 2.Spring Boot 自动装配实现 2.1.@EnableAutoConfiguration 实现 2.1.1. 获取默认包扫描路径 2.1.2.获取自动装配的组件 ...
- Eureka 系列(03)Spring Cloud 自动装配原理
Eureka 系列(03)Spring Cloud 自动装配原理 [TOC] 0. Spring Cloud 系列目录 - Eureka 篇 本文主要是分析 Spring Cloud 是如何整合 Eu ...
- Spring Boot自动配置原理(转)
第3章 Spring Boot自动配置原理 3.1 SpringBoot的核心组件模块 首先,我们来简单统计一下SpringBoot核心工程的源码java文件数量: 我们cd到spring-boot- ...
- Spring Boot自动装配
前言 一些朋友问我怎么读源码,这篇文章结合我看源码时候一些思路给大家聊聊,我主要从这三个方向出发: 确定目标,这个目标要是一个具体,不要一上来我要看懂Spring,这是不可能的,目标要这么来定,比如看 ...
- Spring Boot自动配置原理与实践(二)
前言 在之前的博文(Spring Boot自动配置原理与实践(一))中,已经介绍了Spring boot的自动配置的相关原理与概念,本篇主要是对自动配置的实践,即自定义Starter,对原理与概念加深 ...
- Spring Boot自动配置原理、实战
Spring Boot自动配置原理 Spring Boot的自动配置注解是@EnableAutoConfiguration, 从上面的@Import的类可以找到下面自动加载自动配置的映射. org.s ...
- Spring Boot自动装配原理源码分析
1.环境准备 使用IDEA Spring Initializr快速创建一个Spring Boot项目 添加一个Controller类 @RestController public class Hell ...
随机推荐
- Web Components & HTML template & HTML slot
Web Components & HTML template & HTML slot https://github.com/xgqfrms/es-next/issues/2 live ...
- 扫码登录 & 实现原理
扫码登录 & 实现原理 二维码扫描登录是什么原理? https://time.geekbang.org/dailylesson/detail/100044032 xgqfrms 2012-20 ...
- 时间轴 timeline
时间轴 timeline https://www.helloweba.net/javascript/285.html https://www.helloweba.net/demo/v_timeline ...
- 「NGK每日快讯」12.29日NGK第56期官方快讯!
- Python元组拆包捡到8倍镜快准狠
元组拆包 元组是不可变列表,列表是通过索引取值的,元组也是: tuple_test = (1, 2, 3) a = tuple_test[0] b = tuple_test[1] c = tuple_ ...
- 从微信小程序到鸿蒙js开发【06】——swiper&animator&marquee
目录: 1.swiper轮播图 2.image-animator幻灯片 3.marquee跑马灯 4.nginx动静分离 1.swiper轮播图 微信小程序的swiper组件中只能放置swiper-i ...
- 数据归一化 scikit-learn中的Scaler
1 import numpy as np 2 from sklearn import datasets 3 4 # 获取数据 5 iris = datasets.load_iris() 6 X = i ...
- 文件描述符(File Descriptor)简介
本文转载自文件描述符(File Descriptor)简介 导语 维基百科:文件描述符在形式上是一个非负整数.实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表.当程序打开一个 ...
- sqlserver日期时间格式转换
Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM Select CONVERT(varchar(100), GETDATE( ...
- 多Excel文件内容查询工具。
多Excel文件内容查询工具. 告别繁琐重复的体力劳动,一分钟干完一天的活. 码云 github 下载 当需要在多个Excel表格中查询需要的信息是,一个文件一个文件的去查询非常麻烦. 虽然有其他方法 ...