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 ...
随机推荐
- nyoj-2357
2357: 插塔憋憋乐 时间限制: 1 秒 内存限制: 128 MB提交: 107 解决: 28提交 状态 题目描述 众所不知,LLM是一位红警3大佬,打的非常厉害,但是曾经也是一位萌新,喜欢在家 ...
- 求第n行杨辉三角(n很大,取模
1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 typedef long long l ...
- Gym 101170I Iron and Coal(BFS + 思维)题解
题意:有一个有向图,有些点是煤,有些点是铁,但不会同时有铁和煤.现在我要从1出发,占领可以到达的点.问最少占领几个点能同时拥有一个煤和一个铁(1不用占领). 思路:思路很秀啊.我们从1往外bfs,得到 ...
- CSS Grid & Flex poster PDF 海报定制
CSS Grid & Flex poster PDF 海报定制 CSS 手工实现 导出 SVG / PNG 导出 PDF 打印,定制海报 refs https://css-tricks.com ...
- HTML5 Canvas 画图组件 All In One
HTML5 Canvas 画图组件 All In One Canvas SVG Canvas + SVG refs https://www.infoq.cn/article/1BVg9VDSmqyHv ...
- API & YApi
API & YApi 接口管理服务 YApi http://yapi.demo.qunar.com/ https://ued.qunar.com/ build bug https://gith ...
- Dart & data type(static / dynamic)
Dart & data type(static / dynamic) Darts 飞镖 标枪 javelin/darts type https://dartpad.dartlang.org/ ...
- vue & vue router & match bug
vue & vue router & match bug match bugs solution name must be router https://stackoverflow.c ...
- how to get svg text tspan x,y position value in js
how to get svg text tspan x,y position value in js <svg xmlns="http://www.w3.org/2000/svg&qu ...
- WebAssembly JavaScript APIs
WebAssembly JavaScript APIs https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScrip ...