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 ...
随机推荐
- sdut2879 枚举起点DP
这个题和乌龟棋之类的DP差不多要学会缩减状态 就是,,我们只需枚举当前这个人是谁,选什么颜色,A用了多少,B用了多少 C用了多少我们就不用枚举了,知道选了多少人,A,B用了多少,你还不知C用了多少么, ...
- 『数据结构与算法』二叉查找树(BST)
微信搜索:码农StayUp 主页地址:https://gozhuyinglong.github.io 源码分享:https://github.com/gozhuyinglong/blog-demos ...
- 图解 git stash
图解 git stash # 暂存本地 变化 $ git stash # 复原 $ git stash pop The "git stash" command can help y ...
- vue 自动注册全局组件
vue 自动注册全局组件 vue 注册全局组件的方式 const plugins = { install(Vue) { const requireComponent = require.context ...
- 编程术语 All In One
编程术语 All In One js 名词,术语 函数 函数签名 一个函数签名 (或类型签名,或方法签名) 定义了 函数 或 方法 的输入与输出. 一个签名可以包括: 参数 及参数的 类型 一个返回值 ...
- after upgrade macOS Catalina bugs
after upgrade macOS Catalina bugs 升级了macOS catalina后,碰到的 bugs? macOS 10.15.5 https://www.apple.com/m ...
- TypeScript Learning Paths
TypeScript Learning Paths TypeScript Expert refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以 ...
- js & array remove one item ways
js & array remove one item ways // array remove one item ways let keys = [1,2,3,4,5,6,7]; let ke ...
- Apple & HTML5 app
Apple & HTML5 app https://developer.apple.com/cn/news/?id=09062019b https://developer.apple.com/ ...
- NGK每日快讯2021.1.29日NGK公链第87期官方快讯!