在这里插入图片描述


Spring Boot 之所以能“开箱即用”,其核心就在于 自动配置机制(Auto Configuration)。本文将深入剖析 Spring Boot 自动配置的工作原理,从注解入手,再到底层的源码机制,揭开 Spring Boot 背后的“魔法”。


一、自动配置的初印象

使用 Spring Boot 时,只需加上 @SpringBootApplication 注解,就能启动整个应用,而不需要手动配置 XML 或繁琐的 Java Config。

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

但你有没有想过,是谁帮我们把 Tomcat、DataSource、MVC 等配置都准备好了?

答案就是:Spring Boot 自动配置机制


二、自动配置的核心注解:@EnableAutoConfiguration

@SpringBootApplication 是一个组合注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {
}

其中最关键的就是:

@EnableAutoConfiguration

它的作用就是开启 Spring Boot 自动配置功能


三、@EnableAutoConfiguration 背后的秘密

3.1 @EnableAutoConfiguration 的核心实现

查看源码我们会发现,它用到了 Spring 的 @Import 注解:

@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}

也就是说,它将 AutoConfigurationImportSelector 注册为配置类导入器。

3.2 AutoConfigurationImportSelector 的作用

这个类会扫描 META-INF/spring.factories 文件,并加载所有的自动配置类:

private static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

它会读取其中类似如下的内容:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
...

这些类就是所谓的 自动配置类(AutoConfiguration Class)


四、自动配置类的本质

DataSourceAutoConfiguration 为例:

@Configuration
@ConditionalOnClass(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {...
}

可以看到,它本质上是一个普通的 @Configuration 配置类,但加了一堆 条件注解(Conditional 系列)


五、@Conditional 系列注解实现条件加载

自动配置类并不是一定会生效,而是根据当前环境判断是否生效:

注解功能说明
@ConditionalOnClass类路径中有某个类时才生效
@ConditionalOnMissingBeanSpring 容器中没有指定 Bean 时才生效
@ConditionalOnProperty某个配置属性存在或为指定值时生效
@ConditionalOnWebApplication是 Web 应用时才生效

通过这些注解,Spring Boot 实现了高度解耦、按需加载的自动配置机制。


六、spring.factories 的加载机制

这些自动配置类从哪里来?都定义在 jar 包的:

META-INF/spring.factories

这个文件中,EnableAutoConfiguration 会对应很多个自动配置类列表,它们分布在不同的模块中。

Spring Boot 启动时,会统一通过 SpringFactoriesLoader 加载这些类。

SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, classLoader);

七、自定义自动配置(进阶)

你也可以自己编写自动配置类:

  1. 新建配置类 @Configuration
  2. 加上 @Conditional 条件注解
  3. 注册到 META-INF/spring.factories
@Configuration
@ConditionalOnProperty(name = "my.feature.enabled", havingValue = "true")
public class MyAutoConfiguration {@Beanpublic MyService myService() {return new MyService();}
}
# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfig.MyAutoConfiguration

这样,当配置开启时(my.feature.enabled=true),你的自动配置才会生效。


八、@SpringBootApplication 到底做了什么?

总结起来,@SpringBootApplication 做了三件大事:

  1. @SpringBootConfiguration: 表示这是一个配置类
  2. @ComponentScan: 启动包扫描,自动发现注解的 Bean
  3. @EnableAutoConfiguration: 启动自动配置机制

九、小结:Spring Boot 自动配置的工作流程

graph TD
A[启动类 @SpringBootApplication] --> B[@EnableAutoConfiguration]
B --> C[导入 AutoConfigurationImportSelector]
C --> D[加载 spring.factories]
D --> E[筛选满足条件的自动配置类]
E --> F[按需注册 Bean 到容器中]

这就是 Spring Boot 自动配置的核心原理:通过注解+条件判断+SPI 加载机制,实现了按需配置,极大简化了开发流程。


十、参考资料

  • Spring Boot 官方文档
  • Spring 源码分析
  • 《Spring 实战》第五版

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/91904.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/91904.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/91904.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu18.04开机启动执行脚本

#!/bin/bash # 运行 .NET Core 应用程序 dotnet /home/bruce/atg/SmartConsole.dll &# 打开浏览器 firefox 给文件权限sudo chmod 777 start.sh运行gnome-session-properties打开系统自带的一个启动程序

c语言进阶 字符函数和字符串函数

字符函数和字符串函数字符函数和字符串函数1. strlenstrlen 函数详解模拟实现1.计数器方式2.不能创建临时变量计数器(递归)3.指针-指针的方式2. strcpystrcpy 函数详解模拟实现3. strcatstrcat 函数详解模拟实现4. strcmpstrcmp 函数详解模拟实现5. strn…

(LeetCode 每日一题) 1233. 删除子文件夹 (排序)

题目:1233. 删除子文件夹 思路:排序,时间复杂度0(L*nlogn)。 文件夹a的子文件b,b字符串字典序列一定是大于a的,所以直接将字符串数组folder升序排序。每次只需判断当前字符串,是否是父文件夹数组v最后一个…

集成算法学习bagging,boosting,stacking

baggibg(rf随机森林) adaboostibg 用来展示 Project Jupyter | Home 展示源码 Eclipse IDE | The Eclipse Foundation Eclipse 下载 |Eclipse 基金会 教程8-Adaboost决策边界效果_哔哩哔哩_bilibili (23 封私信) 图解机器学习神器:Scikit-Learn - 知乎 Baggi…

HOOPS SDK赋能PLM:打造全生命周期3D数据管理与协作能力

在制造业和工业领域,产品全生命周期管理(PLM) 已成为驱动企业数字化转型、提升创新力与运营效率的核心引擎。一个高效的PLM平台不仅需要管理海量的设计数据,还必须在设计、制造、供应链、销售和服务等多个环节之间无缝流转信息&am…

解决 Selenium 页面跳转过快导致的内容获取问题:从原理到实践

在使用 Selenium 进行网页自动化操作时,很多开发者都会遇到一个头疼的问题:页面还没加载完,代码就已经执行到下一句了。结果要么是元素找不到,要么是获取的内容不完整,甚至直接抛出异常。今天我们就来聊聊如何优雅地解…

【Python练习】051. 编写一个函数,实现简单的定时器功能

051. 编写一个函数,实现简单的定时器功能 051. 编写一个函数,实现简单的定时器功能 代码说明: 示例运行: 扩展功能 代码说明: 实现Python定时器的几种方法 051. 编写一个函数,实现简单的定时器功能 以下是一个简单的Python函数,用于实现定时器功能。这个定时器可以设置…

springboot基础-demo

1.创建学生信息表 create table stu(id int unsigned primary key auto_increment comment ID,name varchar(100) comment 姓名,age tinyint unsigned comment 年龄,gender tinyint unsigned comment 性别, 1:男, 2:女,score double(5,2) comment 成绩,phone varchar(11) comme…

关于transformer的一些疑点总结

残差连接的作用 Transformer中的残差连接(Residual Connection)是其深层架构能稳定训练的核心设计之一,主要通过以下机制发挥作用: 1. 缓解梯度消失,支持深层训练 梯度保护机制:在反向传播时,…

【终极指南】解决 Windows 11 更新后 Docker 连接 localhost 奇慢(卡顿、超时十几秒)的通用方案

聪明人能看得出这是 ai 写的,但也是我亲身实践的,最后让 ai 总结写了一篇,放心食用 一、 结论先行(直接用)问题现象: 升级到某个 Windows 11 版本后,在本地访问 Docker 容器中部署的任何服务&am…

Stream API

Java 8 引入的 Stream API 是处理集合数据的强大工具,它允许你以声明式方式处理数据集合,支持各种聚合操作和并行处理。以下是 Stream API 的核心知识点及具体代码示例: 1. Stream 概述 Stream 是数据渠道,用于操作数据源&#xf…

相机参数的格式与作用

在计算机视觉中,相机标定是非常重要的一步,主要目的是从图像中恢复出物体的三维信息。为了做到这一点,我们需要了解和使用一系列的数学工具,这些工具描述了相机的成像过程,包括相机的内参、外参、畸变系数、投影矩阵和…

【jvm|基本原理】第四天

摘要:本文简单分析了Java虚拟机的核心运行机制。首先介绍了基本数据类型在32位和64位虚拟机中的存储差异,说明slot槽设计以空间换时间的优化思路。其次详细解析了对象在堆内存中的存储结构,包括对象头、对象数据和对齐填充机制。然后探讨了方…

Git高级操作与最佳实践详解

前言 熟练掌握Git的高级操作可以显著提高开发效率,优化工作流程,解决复杂问题。本文将详细介绍Git的高级操作技巧与最佳实践,帮助开发者更加高效地管理代码和协作开发。 1. 提交历史管理 1.1 修改最近的提交 # 修改最近的提交信息 git co…

ElasticSearch:商品SKU+SPU实现join查询,设计及优化

文章目录一、SPUSKU1、商品SPU和SKU2、SPU和SKU的关系3、实现SPUSKU父子嵌套查询1. **嵌套对象(Nested Objects)**2. **父子关系(Parent-Child)**3. **应用层关联(Application-Side Join)**(推荐…

Objective-c 初阶 —— Runtime(方法交换 消息传递)

一、消息传递1、什么是消息[a func1];我们会把这种用方括号来调函数的方式称为发消息。对于这个例子,就相当于我们给 a 这个对象发了个 func1 的消息(个人认为指令更好理解)。2、什么是 selectorselector 就是一个函数区分器。它只会给这个方…

【计算机网络架构】树型架构简介

引言在当今数字化时代,网络架构如同复杂的神经系统,支撑着各种信息的流通与交互。从个人日常的网络浏览、在线购物,到企业的远程办公、数据存储,再到国家层面的政务信息化、智慧城市建设,网络架构都扮演着不可或缺的角…

llama-factory快速开始

llama-factory快速开始 文章目录llama-factory快速开始前言一、环境配置1.1 训练顺利运行需要包含4个必备条件1.2 llama-factory下载1.3 环境下载1.4 硬件环境校验二、启动前言 https://github.com/hiyouga/LLaMA-Factory/blob/main/README_zh.md这是GitHub中文介绍文档&#…

408数据结构强化(自用)

常用代码片段&#xff08;持续更新&#xff09;折半查找void SearchBinary(int A[];int x){int low 0, high n-1, mid;while(low<high){mid (lowhigh)/2;if(A[mid]x) break;else if(A[mid] < x) low mid 1;else high mid - 1;}顺序表逆置void Reverse(SqList &…

linux cpu频率和AVS调压等级

1&#xff0c;linux常见的cpu频率对应的电压等级对应参数表如下:频率&#xff08;GHz&#xff09;电压&#xff08;V&#xff09;1.61.41.41.21.21.01.00.82&#xff0c;avs调压的几种方式linux内核宏解释Linux内核中&#xff0c;AVS调压的实现依赖于一些宏定义和配置选项&…