当前位置: 首页 > article >正文

Spring Boot 中的自动配置原理

2025/4/6

向全栈工程师迈进!

一、自动配置

所谓的自动配置原理就是遵循约定大约配置的原则,在boot工程程序启动后,起步依赖中的一些bean对象会自动的注入到IOC容器中。

在讲解Spring Boot 中bean对象的管理的时候,我们注入bean对象的过程如下,但这种方式不是自动注入的。 

并没有达到自动配置。 而自动配置是当程序在引入spring-boot-starter-web 起步依赖,boot工程在启动后,会自动往ioc容器中注入DispatcherServlet等bean对象,这就是自动配置。那自动配置的原理是什么呢?

二、自动配置原理

在这里只先引入springboot起步核心依赖,而并没有引入spring-boot-starter-web起步依赖。

<!--引入springboot起步核心依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId>
</dependency>

在没有引入spring-boot-starter-web依赖之前,我们尝试输出spring-boot-starter-web起步依赖会自动注入的bean对象,没有在pom.xml文件中添加改起步依赖时,输出发现根本没有。

package com.example.demo;import org.springframework.context.ApplicationContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Demo1Application {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(Demo1Application.class, args);System.out.println(context.getBean("dispatcherServlet"));}}

导入依赖spring-boot-starter-web后,再次尝试输出其bean对象,发现成功,当引入依赖后,其bean对象被自动的注入了。

2.1 查看@SpringBootApplication注解源码

是组合了以下三个注解

  • @SpringBootConfiguration 其本身也是一个组合注解
  • @EnableAutoConfiguration 其本身也是一个组合注解
  • @ComponentScan 是Bean扫描的注解

@SpringBootConfiguration的内部代码:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.springframework.boot;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Indexed;@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {@AliasFor(annotation = Configuration.class)boolean proxyBeanMethods() default true;
}

可以发现在@SpringBootConfiguration内部也是有@Configuration注解的,所以当在启动类上添加注解@SpringBootApplication其实就是也在启动类上添加了@Configuration注解,所以启动类也是一个配置类。

@EnableAutoConfiguration的内部代码:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.springframework.boot.autoconfigure;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";Class<?>[] exclude() default {};String[] excludeName() default {};
}

@EnableAutoConfiguration是自动配置的核心注解,该@EnableAutoConfiguration注解其实组合了@AutoConfigurationPackage和@Import两个注解,在@Import注解中导入实现类AutoConfigurationImportSelector。其AutoConfigurationImportSelector的实现类如下(代码不全):

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.springframework.boot.autoconfigure;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
........
import org.springframework.util.StringUtils;public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry();private static final String[] NO_IMPORTS = new String[0];private static final Log logger = LogFactory.getLog(AutoConfigurationImportSelector.class);private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude";private ConfigurableListableBeanFactory beanFactory;private Environment environment;private ClassLoader beanClassLoader;private ResourceLoader resourceLoader;private ConfigurationClassFilter configurationClassFilter;public AutoConfigurationImportSelector() {}............private MetadataReaderFactory getMetadataReaderFactory() {try {return (MetadataReaderFactory)this.beanFactory.getBean("org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory", MetadataReaderFactory.class);} catch (NoSuchBeanDefinitionException var2) {return new CachingMetadataReaderFactory(this.resourceLoader);}}}
}

 可以发现在这个实现类(AutoConfigurationImportSelector)中,会从 META-INF/spring.factories 文件中读取所有自动配置类,它读取的 key 是:

org.springframework.boot.autoconfigure.EnableAutoConfiguration

加载所有配置类,条件匹配后注册为 Bean。

2.2 自动配置原理——举个栗子🧩

核心:

AutoConfigurationImportSelector 会从 META-INF/spring.factories 文件中读取所有自动配置类,它读取的 key 是:org.springframework.boot.autoconfigure.EnableAutoConfiguration

你写了一个 Spring Boot 项目,启动类是这样的:

@SpringBootApplication
public class MyApp {public static void main(String[] args) {SpringApplication.run(MyApp.class, args);}
}

 这个注解其实包含了 @EnableAutoConfiguration,表示:

“嘿 SpringBoot,我想用你自动帮我配置一些常见功能,比如数据库、Web、Redis 等!”

 🧠 那 SpringBoot 是怎么知道你要配置啥的?

这时候就轮到 AutoConfigurationImportSelector 出场了!

它是一个“选择器”,全名叫:

org.springframework.boot.autoconfigure.AutoConfigurationImportSelector

它的作用是:

🧭“我去找一个叫 spring.factories 的文件,里面写了:SpringBoot 应该自动配置哪些类。我一个个加载它们,看看哪个需要用,哪个可以跳过。”

📂 spring.factories 是什么?

它是一个纯文本配置文件,路径在:

classpath:/META-INF/spring.factories

这个文件来自哪个 jar 包?👉 就是 Spring Boot 的依赖包之一:

spring-boot-autoconfigure-xxx.jar

打开看一下这个文件长什么样:

# 配置项的 key
org.springframework.boot.autoconfigure.EnableAutoConfiguration=# 配置的值(每一行都是一个自动配置类,全限定类名)
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration

🌟 所以:Spring Boot 会遍历所有这些类,一个个判断:

  • 项目中有没有用到数据库?

  • 类路径中有没有 MySQL 驱动?

  • 你有没有配置 spring.datasource.url

  • 有没有你自己写的 DataSource Bean?

满足这些条件它就帮你创建这个 Bean;不满足,它就跳过。

 如下是我真实项目中其spring.factories文件中的内容。

三、实现自动配置 

自动配置全过程如下:

 

山高路远,我们慢些走,路边有花,远处有彩虹,西边有落日...... 

相关文章:

Spring Boot 中的自动配置原理

2025/4/6 向全栈工程师迈进&#xff01; 一、自动配置 所谓的自动配置原理就是遵循约定大约配置的原则&#xff0c;在boot工程程序启动后&#xff0c;起步依赖中的一些bean对象会自动的注入到IOC容器中。 在讲解Spring Boot 中bean对象的管理的时候&#xff0c;我们注入bean对…...

软考高级-系统架构设计师 论文范文参考(一)

文章目录 论SOA技术的应用论SOA在企业信息化中的应用论UP&#xff08;统一过程方法&#xff09;的应用论分布式数据库的设计与实现论改进Web服务器性能的有关技术论基于UML的需求分析论基于构件的软件开发论基于构件的软件开发(二) 论SOA技术的应用 摘要&#xff1a;  本人于…...

剑指Offer(数据结构与算法面试题精讲)C++版——day16

剑指Offer&#xff08;数据结构与算法面试题精讲&#xff09;C版——day16 题目一&#xff1a;序列化和反序列化二叉树题目二&#xff1a;从根节点到叶节点的路径数字之和题目三&#xff1a;向下的路径节点值之和附录&#xff1a;源码gitee仓库 题目一&#xff1a;序列化和反序…...

windows server C# IIS部署

1、添加IIS功能 windows server 2012、windows server 2016、windows server 2019 说明&#xff1a;自带的是.net 4.5 不需要安装.net 3.5 尽量使用 windows server 2019、2016高版本&#xff0c;低版本会出现需要打补丁的问题 2、打开IIS 3、打开iis应用池 .net 4.5 4、添…...

Android: gradient 使用

在 Android 中使用 gradient&#xff08;渐变&#xff09; 通常是通过 drawable 文件来设置背景。下面是可以直接用的几种用法汇总&#xff0c;包括线性渐变、径向渐变、扫描渐变&#xff08;sweep&#xff09;等&#xff1a; ✅ 1. Linear Gradient&#xff08;线性渐变&#…...

【教程】PyTorch多机多卡分布式训练的参数说明 | 附通用启动脚本

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 torchrun 一、什么是 torchrun 二、torchrun 的核心参数讲解 三、torchrun 会自动设置的环境变量 四、torchrun 启动过程举例 机器 A&#…...

Neo4j初解

Neo4j 是目前应用非常广泛的一款高性能的 NoSQL 图数据库&#xff0c;其设计和实现专门用于存储、查询和遍历由节点&#xff08;实体&#xff09;、关系&#xff08;边&#xff09;以及属性&#xff08;键值对&#xff09;构成的图形数据模型。它的核心优势在于能够以一种自然且…...

学习笔记二十——Rust trait

&#x1f9e9; Rust Trait 彻底搞懂版 &#x1f440; 目标读者&#xff1a;对 Rust 完全陌生&#xff0c;但想真正明白 “Trait、Trait Bound、孤岛法则” 在做什么、怎么用、为什么这样设计。 &#x1f6e0; 方法&#xff1a; 先给“心里模型”——用生活类比把抽象概念掰开揉…...

音视频小白系统入门课-2

本系列笔记为博主学习李超老师课程的课堂笔记&#xff0c;仅供参阅 课程传送门&#xff1a;音视频小白系统入门课 音视频基础ffmpeg原理 往期课程笔记传送门&#xff1a; 音视频小白系统入门笔记-0音视频小白系统入门笔记-1 课程实践代码仓库&#xff1a;传送门 音视频编解…...

Linux:安装 CentOS 7(完整教程)

文章目录 一、简介二、安装 CentOS 72.1 虚拟机配置2.2 安装CentOS 7 三、结语 一、简介 CentOS&#xff08;Community ENTerprise Operating System&#xff09;是一个基于 Linux 的发行版之一&#xff0c;旨在提供一个免费的、企业级的计算平台&#xff0c;因其稳定性、安全…...

MATLAB 控制系统设计与仿真 - 34

多变量系统知识回顾 - MIMO system 这一章对深入理解多变量系统以及鲁棒分析至关重要 首先&#xff0c;对于如下系统&#xff1a; 当G(s)为单输入&#xff0c;单输出系统时&#xff1a; 如果&#xff1a; 则&#xff1a; 所以 因此&#xff0c;对于SISO&#xff0c;系统的增…...

【网络】通过Samba实现Window挂在Linux服务器路径

有时候我们去进行内网部署时&#xff0c;会遇到客户或者甲方爸爸说&#xff0c;需要将Linux中的某个路径共享出去到Window上&#xff0c;挂载出比如Z:\这种盘符。通过打开Z盘&#xff0c;来查看服务器的指定目录下的数据。 步骤1&#xff1a; 在Linux中安装samba yum install…...

DevOps 进阶指南:如何让工作流更丝滑?

DevOps 进阶指南:如何让工作流更丝滑? 引言 在 DevOps 世界里,我们追求的是高效、稳定、自动化。但现实总是充满挑战:代码部署失败、CI/CD 过程卡顿、环境不一致……这些痛点让开发和运维团队疲惫不堪。今天,我就来聊聊如何优化 DevOps 工作流,通过实战案例和代码示例,…...

架构思维:缓存层场景实战_读缓存(下)

文章目录 Pre业务场景缓存存储数据的时机与常见问题解决方案1. 缓存读取与存储逻辑2. 高并发下的缓存问题及解决方案3. 缓存预热&#xff08;减少冷启动问题&#xff09; 缓存更新策略&#xff08;双写问题&#xff09;1. 先更新缓存&#xff0c;再更新数据库&#xff08;不推荐…...

uniapp微信小程序实现sse

微信小程序实现sse 注&#xff1a;因为微信小程序不支持sse请求&#xff0c;因为后台给的是分包的流&#xff0c;所以我们就使用接受流的方式&#xff0c;一直接受&#xff0c;然后把接受的数据拿取使用。这里还是使用uniapp的原生请求。 上代码 //注意&#xff1a;一定要下…...

C#语言的区块链

C#语言在区块链开发中的应用 引言 区块链技术自比特币问世以来&#xff0c;逐渐发展成为一种革命性的技术&#xff0c;其在金融、供应链、物联网等各个领域都产生了深远的影响。随着区块链应用的不断增加&#xff0c;开发者对区块链技术的需求也在不断上升。在众多编程语言中…...

Ubuntu服务器日志满audit:backlog limit exceeded了会报错解决方案-Linux 审计系统 (auditd) 工具

auditd 是 Linux 系统中的审计守护进程&#xff0c;负责收集、记录和监控系统安全相关事件。以下是相关工具及其功能&#xff1a; 核心组件 auditd - 审计守护进程 系统的审计服务主程序 收集系统调用信息并写入日志文件 通常存储在 /var/log/audit/audit.log auditctl - 审计控…...

新能源汽车能量流测试的传感器融合技术应用指南

第一部分&#xff1a;核心原理模块化拆解 模块1&#xff1a;多源传感器物理层融合 关键技术&#xff1a; 高精度同步采集架构 采用PXIe-8840控制器同步定时模块&#xff08;NI PXIe-6674T&#xff09;&#xff0c;实现CAN/LIN/模拟量信号的μs级同步光纤电压传感器&#xff0…...

人工智能与网络安全:AI如何预防、检测和应对网络攻击?

引言&#xff1a;网络安全新战场&#xff0c;AI成关键角色 在数字化浪潮不断推进的今天&#xff0c;网络安全问题已经成为每一家企业、每一个组织无法回避的“隐形战场”。无论是电商平台、金融机构&#xff0c;还是政府机关、制造企业&#xff0c;都可能面临数据泄露、勒索病毒…...

链表知识回顾

类型&#xff1a;单链表&#xff0c;双链表、循环链表 存储&#xff1a;在内存中不是连续存储 删除操作&#xff1a;即让c的指针指向e即可&#xff0c;无需释放d&#xff0c;因为java中又内存回收机制 添加节点&#xff1a; 链表的构造函数 public class ListNode {// 结点…...

FPGA学习(五)——DDS信号发生器设计

FPGA学习(五)——DDS信号发生器设计 目录 FPGA学习(五)——DDS信号发生器设计一、FPGA开发中常用IP核——ROM/RAM/FIFO1、ROM简介2、ROM文件的设置&#xff08;1&#xff09;直接编辑法&#xff08;2&#xff09;用C语言等软件生成初始化文件 3、ROM IP核配置调用 二、DDS信号发…...

【数据结构入门训练DAY-18】信息学奥赛一本通T1331-后缀表达式的值

文章目录 前言一、题目二、解题思路总结 前言 本次训练内容&#xff1a; 栈的复习。栈模拟四则运算计算问题的练习。训练解题思维。 一、题目 从键盘读入一个后缀表达式&#xff08;字符串&#xff09;&#xff0c;只含有0-9组成的运算数及加&#xff08;&#xff09;、减…...

OpenCv高阶(六)——图像的透视变换

目录 一、透视变换的定义与作用 二、透视变换的过程 三、OpenCV 中的透视变换函数 1. cv2.getPerspectiveTransform(src, dst) 2. cv2.warpPerspective(src, H, dsize, dstNone, flagscv2.INTER_LINEAR, borderModecv2.BORDER_CONSTANT, borderValue0) 四、文档扫描校正&a…...

性能比拼: Go vs Bun

本内容是对知名性能评测博主 Anton Putra Go (Golang) vs. Bun: Performance (Latency - Throughput - Saturation - Availability) 内容的翻译与整理, 有适当删减, 相关指标和结论以原作为准 我对 Bun 在之前的基准测试中的出色表现感到惊讶&#xff0c;因此我决定将它与 Go …...

定制化 Docsify 文档框架实战分享

&#x1f31f; 定制化 Docsify 文档框架实战分享 在构建前端文档平台时&#xff0c;我们希望拥有更友好的用户界面、便捷的搜索、清晰的目录导航以及实用的代码复制功能。借助 Docsify&#xff0c;我实现了以下几个方面的定制优化&#xff0c;分享给大家 &#x1f64c;。 &…...

Qt中读写结构体字节数据

在Qt中读写结构体字节数据通常涉及将结构体转换为字节数组(QByteArray)或直接从内存中读写。以下是几种常见方法&#xff1a; 方法1&#xff1a;使用QDataStream读写结构体 cpp #include <QFile> #include <QDataStream>// 定义结构体 #pragma pack(push, 1) //…...

鸿蒙ArkUI之布局实战,线性布局(Column,Row)、弹性布局(Flex)、层叠布局(Stack),详细用法

本文聚焦于ArkUI的布局实战&#xff0c;三种十分重要的布局&#xff0c;线性布局、弹性布局、层叠布局&#xff0c;在实际开发过程中这几种布局方法都十分常见&#xff0c;下面直接上手 线性布局 垂直布局&#xff08;Column&#xff09; 官方文档&#xff1a; Column-行列…...

测试基础笔记第七天

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、cat命令二、ls -al命令三、>重定向符号四、>>追加重定向符号五、less/more命令六、grep命令七、|管道符八、clear命令九、head命令十、tail命令十一、…...

[Windows] Adobe Camera Raw 17.2 win/Mac版本

[Windows] Adobe Camera Raw 链接&#xff1a;https://pan.xunlei.com/s/VOOIAXoyaZcKAkf_NdP-qw_6A1?pwdpd5k# Adobe Camera Raw&#xff0c;支持Photoshop&#xff0c;lightroom等Adobe系列软件&#xff0c;对相片无损格式进行编辑调色。 支持PS LR 2022 2023 2024 2025版…...

开源模型应用落地-Podcastfy-从文本到声音的智能跃迁-Gradio(一)

一、前言 在当今信息呈现方式越来越多样化的背景下&#xff0c;如何将文字、图片甚至视频高效转化为可听的音频体验&#xff0c;已经成为内容创作者、教育者和研究者们共同关注的重要话题。Podcastfy是一款基于Python的开源工具&#xff0c;它专注于将多种形式的内容智能转换成…...