重学SpringBoot3-自动配置机制
重学SpringBoot3-自动配置机制
- 引言
- Spring Boot 自动配置原理
- 示例:Spring Boot Web 自动配置
- 深入理解
- 总结
- 相关阅读
引言
Spring Boot 的自动配置是其最强大的特性之一,它允许开发者通过最少的配置实现应用程序的快速开发和部署。这一切都得益于 Spring Boot 的 “约定优于配置” 的设计理念。本教程将带你了解 Spring Boot 自动配置的背后原理,并通过示例解释其工作方式。
Spring Boot 自动配置原理
Spring Boot
自动配置的核心是一系列自动配置类,这些类通常基于类路径中的存在和属性值来条件性地配置应用程序。
主要步骤如下:
-
启动类:每个
Spring Boot
应用都有一个启动类,通常使用@SpringBootApplication
注解。这个注解是一个组合的注解,它包含了@EnableAutoConfiguration
,后者是自动配置的关键。 -
@EnableAutoConfiguration:这个注解告诉
Spring Boot
开始扫描候选自动配置类,并应用它们。这些候选自动配置类通常通过spring.factories
文件存放,该文件位于自动配置模块的META-INF/
目录下。 -
条件注解:自动配置类使用条件注解(如
@ConditionalOnClass
、@ConditionalOnBean
、@ConditionalOnProperty
等)来确保只有在特定条件满足时才应用配置。例如,某个自动配置类可能只在某个类存在于类路径上时才激活。 -
属性绑定:自动配置过程还涉及将外部配置(如
application.properties
或application.yml
)绑定到配置类上,进一步定制化自动配置。
相关源码:
从启动类开始
@SpringBootApplication
注解其实包含三个注解,自动配置相关的是@EnableAutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration
:通过@Import
导入自动配置模块的导入选择器AutoConfigurationImportSelector,它的作用是在启动时扫描指定包路径下的所有自动配置类,并根据应用程序的依赖关系和环境变量等信息,自动地选择需要引入的自动配置类,并将其注册为Bean
,以便应用程序可以正常使用这些自动配置的功能。
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports
:该方法的主要作用是从给定的注解元数据中筛选出需要导入的包名。
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntry
:用于获取自动配置项的入口点。该方法接受一个参数,即要获取的自动配置项的名称。它返回一个AutoConfigurationEntry
对象,该对象包含了自动配置项的详细信息,如类路径、Bean
定义等。重点看该方法内调用的getCandidateConfigurations()
方法。
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getCandidateConfigurations
:这个方法的作用是获取候选的自动配置类列表。
org.springframework.boot.context.annotation.ImportCandidates#load
:通过调用ImportCandidates.load()
方法,从META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件中加载候选的自动配置类,并将其存储在configurations
变量中。
org.springframework.boot.autoconfigure.AutoConfiguration.imports
:存放了SpringBoot
自动配置类,不同SpringBoot
版本数量不同。
回到
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntry
,会对读到所有的自动配置类进行筛选。
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.ConfigurationClassFilter#filter
:筛选条件就是使用条件注解(如@ConditionalOnClass
、@ConditionalOnBean
、@ConditionalOnProperty
等)来确保只有在特定条件满足时才应用配置。
例如符合筛选条件的
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration
自动配置类,类上带有@EnableConfigurationProperties({ServerProperties.class})
,既将配置文件(如application.properties
或application.yml
)中的属性绑定到带有@ConfigurationProperties
注解的类ServerProperties.class
对象上,从而达到引入starter
配置少量参数就能运行的目的。
示例:Spring Boot Web 自动配置
假设你想创建一个简单的 Spring Boot Web 应用。你只需要做以下几步:
-
添加依赖:在
pom.xml
或build.gradle
文件中添加Spring Boot Starter Web
依赖。<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency>
-
创建启动类:
@SpringBootApplication public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);} }
-
编写控制器:
@RestController public class HelloController {@GetMapping("/")public String hello() {return "Hello, Spring Boot!";} }
-
配置文件
server.port=8808
在这个例子中,spring-boot-starter-web
包含了 Spring MVC
和 Tomcat
作为默认的嵌入式服务器,以及其他 Web
开发所需的依赖。当你启动应用时,Spring Boot
的自动配置会检测到类路径上的 spring-webmvc
和嵌入式 Tomcat
,并自动配置它们。这意味着你通过少量的配置或默认配置就可以运行一个基本的 Web 应用。
深入理解
-
自定义自动配置:如果默认的自动配置不符合你的需求,你可以通过添加自定义配置来覆盖或补充默认配置。此外,你也可以通过排除特定的自动配置类来禁用它们。
-
条件化配置:理解自动配置背后的条件逻辑对于高效使用
Spring Boot
非常重要。你可以查看特定自动配置类的源码,以了解它们是如何根据应用的状态和外部配置做出决策的。
总结
Spring Boot
的自动配置极大简化了 Spring
应用的配置工作,让开发者可以专注于应用逻辑的实现,而非繁琐的配置。通过合理利用自动配置和条件注解,你可以快速地构建出既强大又灵活的 Spring
应用。了解并掌握 Spring Boot
自动配置的原理和使用方法,将有助于你更高效地开发 Spring Boot
应用。
相关阅读
重学SpringBoot3-@Import注解的作用
重学SpringBoot3-@ConditionalOnXxx条件注解
重学SpringBoot3-@ConditionalOnXxx条件注解
重学SpringBoot3-@EnableConfigurationProperties注解
相关文章:

重学SpringBoot3-自动配置机制
重学SpringBoot3-自动配置机制 引言Spring Boot 自动配置原理示例:Spring Boot Web 自动配置深入理解总结相关阅读 引言 Spring Boot 的自动配置是其最强大的特性之一,它允许开发者通过最少的配置实现应用程序的快速开发和部署。这一切都得益于 Spring …...

sql基本语法+实验实践
sql语法 注释: 单行 --注释内容# 注释内容多行 /* 注释内容 */数据定义语言DDL 查询所有数据库 show databases;注意是databases而不是database。 查询当前数据库 select database();创建数据库 create database [if not exists] 数据库名 [default charset 字符…...

Node.js中的并发和多线程处理
在Node.js中,处理并发和多线程是一个非常重要的话题。由于Node.js是单线程的,这意味着它在任何给定时间内只能执行一个任务。然而,Node.js的事件驱动和非阻塞I/O模型使得处理并发和多线程变得更加高效和简单。在本文中,我们将探讨…...
node.js 封装分页查询
node.js封装sql分页查询 方法: /*** 生成分页查询sql* param {string} table 表名* param {number} pageNum 分页页数 * param {number} pageSize 分页条数 * param {object} query 查询对象 例:{id:1,name:小明}* returns sql语句*/ const limit (ta…...
iptables 基本使用
iptables 主要用到两个表:filter 和 nat,其中 filter 表可以用来过滤数据包;nat 可以用来修改数据包的源地址和目的地址。 chain chain 是 table 中对数据包进行匹配的规则,对于 filter 来说 chain 有 INPUT & OUTPUT & …...
食品笔记()
吃东西有时不注意,就容易不舒服,记录下。 辣椒 辣椒真是个让人又爱又恨的东西。 看着想吃,吃着过瘾,吃完容易肚子疼。 主要是这东西本身就会刺激身体,即使是能吃辣的人,也容易造成肠胃发炎。 适量吃些即…...

C++入门和基础
目录 文章目录 前言 一、C关键字 二、命名空间 2.1 命名空间的定义 2.2 命名空间的使用 2.3 标准命名空间 三、C输入&输出 四、缺省参数 4.1 缺省参数的概念 4.2 缺省参数的分类 五、函数重载 5.1 函数重载的简介 5.2 函数重载的分类 六、引用 6.1 引用的…...

一些C语言知识
C语言的内置类型: char short int long float double C99中引入了bool类型,用来表示真假的变量类型,包含true,false。 这个代码的执行结果是什么?好好想想哦,坑挺多的。 #include <stdio.h>int mai…...

代码工具APEX的入门使用(未包含安装)
第一次使用APEX是2019年,这个技术成名已久只是我了解的比较晚。请看Oracle ACE的网站,这就是用APEX做的。实际上有一次我看O记的人操作他们的办公流程,都是用APEX做的。 那一年,我用APEX做了一个CMDB的管理系统。那时候还没有流行…...

负载均衡.
简介: 将请求/数据【均匀】分摊到多个操作单元上执行,负载均衡的关键在于【均匀】。 负载均衡的分类: 网络通信分类 四层负载均衡:基于 IP 地址和端口进行请求的转发。七层负载均衡:根据访问用户的 HTTP 请求头、URL 信息将请求转发到特定的主机。 载体维度分类 硬…...

Git 指令深入浅出【2】—— 分支管理
Git 指令深入浅出【2】—— 分支管理 分支管理1. 常用分支管理指令2. 合并分支合并冲突合并模式 3. 实战演习 分支管理 1. 常用分支管理指令 # 查看本地分支 git branch# 查看远程分支 git branch -r# 查看全部分支 git branch -aHEAD 指向的才是当前的工作分支 # 查看当前分…...
工作流/任务卸载相关开源论文分享
decima-sim 概述: 图神经网络强化学习处理多工作流 用的spark的仿真环境,mit的论文,价值很高,高被引:663仓库地址:https://github.com/hongzimao/decima-sim论文:https://web.mit.edu/decima/co…...
为什么要用Python?
为什么要用Python? Python简单易用:提供大量的简单易用数据结构和内置库,语法结构也很简单易读,不需要使用括号来进行代码块分组,也不需要预声明变量或参数。Python开发效率高:简单易用的前提下࿰…...

北京大学发布,将试错引入大模型代理学习!
引言:探索语言智能的新边界 在人工智能的发展历程中,语言智能始终是一个核心的研究领域。随着大语言模型(LLM)的兴起,我们对语言智能的理解和应用已经迈入了一个新的阶段。这些模型不仅能够理解和生成自然语言&#x…...
Java 设计模式
编程设计模式六大原则 开闭原则(Open Close Principle):对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好&#…...
Kivy和BeeWare 开发APP的优缺点,及其发展历史
Kivy和BeeWare都是流行的Python框架,用于开发移动应用。它们各自有独特的特点和优势,同时也面临一些挑战和限制。下面是对这两个框架的开发优缺点及其发展历史的总结。 Kivy 发展历史 起源:Kivy诞生于2010年,旨在提供一个用于P…...
C++递推
统计每个月兔子的总数 #include<bits/stdc.h> using namespace std; int n,sum0; void f(int); int main() {int a[1000];cin>>n;a[1]1;a[2]2;for(int i3;i<1000;i){a[i]a[i-1]a[i-2];}cout<<a[n];return 0; } void f(int n){}猴子吃桃子 #include<b…...
C++ 面试题
一、基础语法 1. C 和 C的区别 i. C是面向对象的的编程语言,C是面向过程的编程语言 ii. C中的内存分配运算符是new/delete而C 中是malloc和free iii. C中有函数重载而C 中没有 iv. C中新增了引用的概念而C 中只有值和指针 2. struct 和 class的区别 i. struc…...

MySQL之索引详解
华子目录 索引概述优缺点 索引的原理索引的设计原则索引结构B-tree(多路平衡查找树)BtreeHash 为什么InnoDB存储引擎选择Btree?索引分类聚集索引选取规则 单列索引和多列索引前缀索引创建索引1.创建表时创建索引2.在已经存在的表上创建索引3.…...

Java面试题总结8:springboot
Spring Boot自动配置原理 importConfigurationSpring spi 自动配置类由各个starter提供,使用ConfigurationBean定义配置类,放到META-INF/spring.factories下 使用Spring spi扫描META-INF/Spring.factories下的配置类 如何理解Spring Boot中Starter …...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...