源码角度解析SpringBoot 自动配置
文章目录
- 前言
- 一、了解相关注解
- 1.@Condition注解
- 2.@Enable注解
- 二、SpringBoot自动配置
- 1.@SpringBootApplication注解
- 2.@SpringBootConfiguration注解
- 3.@EnableAutoConfiguration注解
- 4.@Conditional注解
- 总结
前言
Spring Boot 自动配置是 Spring Boot 的核心特性之一,它的目标是通过分析应用程序的类路径(classpath)和依赖关系,来自动配置 Spring 应用程序所需的 Bean、设置和组件。这意味着开发人员不需要手动配置大部分常见的 Spring 组件,Spring Boot 将根据环境和依赖来进行智能配置。这样,开发人员可以专注于编写业务逻辑,而不必过多关心底层配置细节。
一、了解相关注解
1.@Condition注解
Condition 是在Spring 4.0 增加的条件判断功能,通过这个可以功能可以实现选择性的创建 Bean 操作。
SpringBoot 提供的常用条件注解:
- @ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化Bean
- @ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean
- @ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean
- @ConditionalOnBean:判断环境中有对应Bean才初始化Bean
2.@Enable注解
SpringBoot中提供了很多Enable开头的注解,这些注解都是用于动态启用某些功能的。而其底层原理是使用@Import注 解导入一些配置类,实现Bean的动态加载。
@Enable底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中。而@Import提供4中用法:
① 导入Bean;
@Import(User.class)
② 导入配置类;
@Import(UserConfig.class)
③ 导入 ImportSelector 实现类。一般用于加载配置文件中的类;
@Import(MyImportSelector.class)
④ 导入 ImportBeanDefinitionRegistrar 实现类。
@Import({MyImportBeanDefinitionRegistrar.class})
二、SpringBoot自动配置
1.@SpringBootApplication注解
主启动类注解:
package org.springframework.boot.autoconfigure;
@Targer(ElementType.TYPE)//作用于类
@Retention(Retention.RUNTIME)//该注解在运行时可见,可以通过反射读取
@Documented//文档相关
@Inherited//可以被子类继承
@SpringBootConfiguration//标记该类为 Spring Boot 的配置类
@EnableAutoConfiguration//实现自动配置功能
@ComponentScan(excludeFilters = {@Filter(type=FilterType.CUSTOM,classes = TypeExcludeFilter.class),@Filter(type=FilterType.CUSTOM,classes = AutoConfigurationExcludeFilter.class)
})//配置组件扫描,以查找和注册 Spring Bean
public @interface SpringBootApplication{……}
总的来说,大概可以把@SpringBootApplication看作是@Configuration、@EnableAutoConfigeration、@ComponentScan注解的集合。
@EnableAutoConfigeration:启用SpringBoot的自动配置机制;
@ComponentScan:扫描被@Component(@Service,@Controller)注解的bean,注解默认会扫描该类所在包下的所有的类;
@Configuration:允许在上下文中注册额外的bean或倒入其他配置类。
2.@SpringBootConfiguration注解
SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;
//这里的@Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;
@Configuration
public @interface SpringBootConfiguration {}
//里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用
@Component
public @interface Configuration {....}
3.@EnableAutoConfiguration注解
@EnableAutoConfiguration开启自动配置功能,它可以说是我们研究SpringBoot 自动配置的重中之重了:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {.....}
3.1@AutoConfigurationPackage注解:
//AutoConfigurationPackage的子注解
//Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
}
在默认的情况下就是将:主配置类(@SpringBootApplication)的所在包及其子包里边的组件扫描到Spring容器中。
3.2@Import({AutoConfigurationImportSelector.class})注解:给容器导入组件
AutoConfigurationImportSelector :自动配置导入选择器,给容器中导入一些组件;
通过了@import注解导入了AutoConfigurationImportSelector这个配置类,根据类名可以发现,这个实现类是@Import提供4中用法中的ImportSelector的实现类,那么它就一定实现了selectImports这个个方法:
String[] selectImports(AnnotationMetadata importingClassMetadata);
该方法的主要目的是根据运行时的条件或配置动态地确定要导入哪些配置类,以扩展或自定义 Spring 应用程序的配置。
返回值是一个字符串数组,其中包含需要导入到当前配置类中的其他配置类的全限定类名。
那我们就来看看他是怎么来重写这个方法的:
public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!this.isEnabled(annotationMetadata)) {return NO_IMPORTS;} else {AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}}
this.isEnabled(annotationMetadata) 方法检查是否启用了自动配置。如果没有启用,就返回一个空数组 NO_IMPORTS,表示不导入任何配置类。
getAutoConfigurationEntry(annotationMetadata) 方法来获取自动配置入口,那么他是如何去获取的呢?继续进方法看看:
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
用于根据给定的注解元数据 (annotationMetadata) 和属性 (attributes) 获取潜在的自动配置类的列表,它的作用就是找到所有可能与应用程序上下文相关的自动配置类。
↓ ↓ ↓
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List<String> configurations = new ArrayList(SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()));ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).forEach(configurations::add);Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.");return configurations;}
这个方法想告诉我们什么呢,其实看到这里官方给出的提示就已经很明显了:
在META-INF/spring中找不到自动配置类。在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中。如果您正在使用自定义打包,请确保该文件是正确的。
简但来说,就是在所有包名叫做autoConfiguration的包下面都有META-INF/spring.factories文件,Spring启动的时候会扫描这个文件,将其文件包装成Properties对象从Properties对象获取到key值为EnableAutoConfiguration的数据,然后添加到容器里边。

4.@Conditional注解
现在SpringBoot自动配置信息有了,自动配置还差什么呢?
到这一步为止,SpringBoot已经为我们的项目中导入了大量的自动配置类,且项目中的自动配置类全部执行,但是这133个自动配置类我们都会用到吗?
以RedisAutoConfiguration为例:

看到这里就不难发现,虽然SpringBoot帮我们加载了Redis的自动配置类,但并没有把redisTemplate模板类帮我们注入容器,真正想要注入模板类到容器里供我们使用之前,还要经过一些选择注解的判断且全部成功才可以成功注入。
以redisTemplate模板类为例,它想要成功注入,就得经过三个选择注解的全部成功才可以注入:
//项目中必须要有RedisProperties这个类才可以生效(坐标中倒入)
@EnableConfigurationProperties({RedisProperties.class})
//容器中必须没有一个Bean为redisTemplate,这也就允许我们自己向容器中注入一个redisTemplate!
@ConditionalOnMissingBean(name = {"redisTemplate"})//指定必须是单例工厂才能生效
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
只有在经过这三个选择注解后,自动装配才算真正完成,redisTemplate类才能供我们在项目中使用。
总结
- @EnableAutoConfiguration 注解内部使用@Import(AutoConfigurationImportSelector.class)来加载配置类;
- 配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当 SpringBoot应用启动时,会自动加载这些配置类,初始化Bean;
- 并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足条件的Bean。
相关文章:
源码角度解析SpringBoot 自动配置
文章目录 前言一、了解相关注解1.Condition注解2.Enable注解 二、SpringBoot自动配置1.SpringBootApplication注解2.SpringBootConfiguration注解3.EnableAutoConfiguration注解4.Conditional注解 总结 前言 Spring Boot 自动配置是 Spring Boot 的核心特性之一,它…...
【原创】H3C路由器OSPF测试
网络拓扑图 路由器配置: 路由器1上接了4跟线,分别为这四个接口配置IP地址。 # interface GigabitEthernet0/0/0port link-mode routecombo enable copperip address 2.1.1.2 255.255.255.0 # interface GigabitEthernet0/0/1port link-mode routecombo…...
计算机视觉:轨迹预测综述
计算机视觉:轨迹预测综述 轨迹预测的定义轨迹预测的分类基于物理的方法(Physics-based)基于机器学习的方法(Classic Machine Learning-based)基于深度学习的方法(Deep Learning-based)基于强化学…...
三维跨孔电磁波CT数据可视化框架搭建
三维跨孔电磁波CT数据可视化框架搭建 文章目录 三维跨孔电磁波CT数据可视化框架搭建1、三维CT可视化结果2、matlab代码2.1、CT数据格式整理并保存2.2、三维可视化 利用matlab实现对跨孔电磁波CT实测数据反演,并搭建了三维CT数据可视化框架,可装填实测CT反…...
OC和Swift混编,导入头文件‘xxx-Swift.h‘ file not found
在OC的项目里加入Swift代码,创建完桥接文件后,需要倒入Swift头文件,头文件的格式为“项目名-Swift.h”。 如下图,我在Xcode上看到我的项目名为YichangPark,导入 #import "YiChangPark-Swift.h" 之后提示 “Y…...
一文读懂HOOPS Native平台:快速开发桌面端、移动端3D应用程序!
HOOPS Native Platform是用于在桌面和移动平台以及混合现实应用程序上构建3D工程应用程序的首要工具包。它由三个集成良好的软件开发工具包(SDK)组成:HOOPS Visualize、HOOPS Exchange、HOOPS Publish。HOOPS Visualize 是一个强大的图形引擎,适用于本机…...
Scrum工作模式及Scrum工具
Scrum工作模式是一种敏捷软件开发方法,其核心是团队合作和自我组织,旨在通过短周期的迭代开发,实现快速反馈和持续改进。 Scrum工作模式包括以下角色和活动: 1、产品负责人(Product Owner):负…...
[ros][ubuntu]ros在ubuntu18.04上工作空间创建和发布一个话题
构建catkin工作空间 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src catkin_init_workspace cd ~/catkin_ws/ catkin_make 配置环境变量 echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc source ~/.bashrc 检查环境变量 echo $ROS_PACKAGE_PATH…...
我的区块链笔记
区块链 中心化的账本,个人节点和中心节点的地位不对等,中心节点说了算。去中心化,个人节点就是公平的,根据一套规则,叫做公比机制。 区块链的本质,就是数据存储方式 区块链使用密码学算法产生的区块&…...
Spring事务(ACID特性、隔离级别、传播机制、失效场景)
一、事务的ACID特性 原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。一致性(Consistency) 事务前后数据的完整性必须保持一致。隔离性(Isola…...
机器学习笔记之最优化理论与方法(六)无约束优化问题——最优性条件
机器学习笔记之最优化理论与方法——无约束优化问题[最优性条件] 引言无约束优化问题无约束优化问题最优解的定义 无约束优化问题的最优性条件无约束优化问题的充要条件无约束优化问题的必要条件无约束优化问题的充分条件 引言 本节将介绍无约束优化问题,主要介绍无…...
E5061B/是德科技keysight E5061B网络分析仪
181/2461/8938产品概述 是德科技E5061B(安捷伦)网络分析仪在从5 Hz到3 GHz的宽频率范围内提供通用的高性能网络分析。E5061B提供ENA系列常见的出色RF性能,还提供全面的LF(低频)网络测量能力;包括内置1 Mohm输入的增益相位测试端口。E5061B从低频到高频的…...
2.4 PE结构:节表详细解析
节表(Section Table)是Windows PE/COFF格式的可执行文件中一个非常重要的数据结构,它记录了各个代码段、数据段、资源段、重定向表等在文件中的位置和大小信息,是操作系统加载文件时根据节表来进行各个段的映射和初始化的重要依据…...
Vue2项目练手——通用后台管理项目第五节
Vue2项目练手——通用后台管理项目 首页组件布局面包屑&tag面包屑使用组件使用vuex存储面包屑数据src/store/tab.jssrc/components/CommonAside.vuesrc/components/CommonHeader.vue tag使用组件文件目录CommonTag.vueMain.vuetabs.js 用户管理页新增功能使用的组件页面布局…...
软件工程学术顶会——ESEC/FSE 2022 议题(网络安全方向)清单、摘要与总结
总结 本次会议中网络安全相关议题涵盖区块链、智能合约、符号执行、浏览器API模糊测试等不同研究领域。 热门研究方向: 1. 基于深度学习的漏洞检测与修复 2. 基于AI的自动漏洞修复 3. 模糊测试与漏洞发现 冷门研究方向: 1. 多语言代码的漏洞分析 2. 代码审查中的软件安全 3. 浏…...
从C语言到C++_36(智能指针RAII)auto_ptr+unique_ptr+shared_ptr+weak_ptr
目录 1. 智能指针的引入_内存泄漏 1.1 内存泄漏 1.2 如何避免内存泄漏 2. RAII思想 2.1 RAII解决异常安全问题 2.2 智能指针原理 3. auto_ptr 3.1 auto_ptr模拟代码 4. unique_ptr 4.1 unique_ptr模拟代码 5. shared_ptr 5.1 shared_ptr模拟代码 5.2 循环引用 6.…...
C++信息学奥赛1187:统计字符数
#include <bits/stdc.h> using namespace std; int main() {string arr;cin >> arr; // 输入一个字符串int n, a, max; // 定义变量n, a, maxchar ArrMax; // 定义字符变量ArrMaxn arr.length(); // 获取字符串长度max a 0; // 初始化max和a为0// 外层循环&…...
计算机毕设 大数据商城人流数据分析与可视化 - python 大数据分析
文章目录 0 前言课题背景分析方法与过程初步分析:总体流程:1.数据探索分析2.数据预处理3.构建模型 总结 最后 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到…...
vscode上搭建go开发环境
前言 Go语言介绍: Go语言适合用于开发各种类型的应用程序,包括网络应用、分布式系统、云计算、大数据处理等。由于Go语言具有高效的并发处理能力和内置的网络库,它特别适合构建高并发、高性能的服务器端应用。以下是一些常见的Go语言应用开发…...
10.(Python数模)(预测模型二)LSTM回归网络(1→1)
LSTM回归网络(1→1) 长短期记忆网络 - 通常只称为“LSTM” - 是一种特殊的RNN,能够学习长期的规律。 它们是由Hochreiter&Schmidhuber(1997)首先提出的,并且在后来的工作中被许多人精炼和推广。…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
密码学基础——SM4算法
博客主页:christine-rr-CSDN博客 专栏主页:密码学 📌 【今日更新】📌 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 编辑…...
