Springboot基础篇(4):自动配置原理
1 自动配置原理剖析
1.1 加载配置类的源码追溯
- 自动配置的触发入口:
@SpringBootApplication组合注解是自动配置的起点,其核心包含@EnableAutoConfiguration,该注解使用AutoConfigurationImportSelector实现配置类的动态加载。

//可以应用于类、接口(包括注解类型)和枚举声明
@Target(ElementType.TYPE)
//注解信息将在运行时保留
@Retention(RetentionPolicy.RUNTIME)
//在使用 Javadoc 工具生成 API 文档时,该注解将被包含在文档中
@Documented
//如果一个类使用了@SpringBootApplication 注解,那么它的子类也会继承这个注解
@Inherited
//springboot配置类
@SpringBootConfiguration
//核心:启用Spring Boot 的自动配置机制
@EnableAutoConfiguration
//启用组件扫描
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication{}
- 查看@EnableAutoConfiguration,@EnableAutoConfiguration注解上导入了AutoConfigurationImportSelector.class,该类负责选择和导入需要自动配置的类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
//指定自动配置的包路径,通常用于扫描带有@Configuration 注解的类
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}
- 查看AutoConfigurationImportSelector.class,该类负责加载、筛选和返回需要加载的自动配置类
public class AutoConfigurationImportSelector implements ... {// 核心方法:选择并加载自动配置类
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {// 1. 检查是否启用自动配置if (!isEnabled(annotationMetadata)) {return NO_IMPORTS; // 如果未启用,返回空数组}// 2. 获取自动配置条目AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);// 3. 返回配置类数组return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
- 查看selectImports中调用的getAutoConfigurationEntry方法。
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {// 1. 检查是否启用自动配置if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY; // 如果未启用,返回空条目}// 2. 获取注解属性AnnotationAttributes attributes = getAttributes(annotationMetadata);// 3. 加载候选配置类List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);// 4. 去重configurations = removeDuplicates(configurations);// 5. 获取排除项Set<String> exclusions = getExclusions(annotationMetadata, attributes);// 6. 检查排除项checkExcludedClasses(configurations, exclusions);// 7. 过滤排除项configurations.removeAll(exclusions);// 8. 应用配置类过滤器configurations = getConfigurationClassFilter().filter(configurations);// 9. 触发事件fireAutoConfigurationImportEvents(configurations, exclusions);// 10. 返回结果return new AutoConfigurationEntry(configurations, exclusions);
}
- 查看getAutoConfigurationEntry方法调用的getCandidateConfigurations方法
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {// 1. 加载候选配置类ImportCandidates importCandidates = ImportCandidates.load(this.autoConfigurationAnnotation, getBeanClassLoader());List<String> configurations = importCandidates.getCandidates();// 2. 检查配置类是否为空Assert.notEmpty(configurations,"No auto configuration classes found in " + "META-INF/spring/"+ this.autoConfigurationAnnotation.getName() + ".imports. If you "+ "are using a custom packaging, make sure that file is correct.");// 3. 返回配置类列表return configurations;
}
- 查看getCandidateConfigurations调用的load方法,可以看到该方法负责从类路径中加载指定注解对应的 .imports 文件,并解析文件内容。
public static ImportCandidates load(Class<?> annotation, ClassLoader classLoader) {// 1. 检查注解是否为空Assert.notNull(annotation, "'annotation' must not be null");// 2. 决定类加载器ClassLoader classLoaderToUse = decideClassloader(classLoader);// 3. 构建文件路径String location = String.format("META-INF/spring/%s.imports", annotation.getName());// 4. 查找文件 URLEnumeration<URL> urls = findUrlsInClasspath(classLoaderToUse, location);// 5. 读取文件内容List<String> importCandidates = new ArrayList<>();while (urls.hasMoreElements()) {URL url = urls.nextElement();importCandidates.addAll(readCandidateConfigurations(url));}// 6. 返回结果return new ImportCandidates(importCandidates);
}
- 最后我们终于知道,@SpringBootApplication通过层层修饰,最后到了load方法,load方法扫描并读取类路径下的.imports文件中的配置类。
1.2 通过条件注解注册配置类
我们选择mybatis的包来介绍如何注册的
-
找到mybatis的自动配置包

-
查看.imports文件

-
查看部分配置类:这个类的含义是在满足以下条件时,自动配置并注册一个 FreeMarkerLanguageDriver Bean:
a、 类路径中存在 FreeMarkerLanguageDriver 和 FreeMarkerLanguageDriverConfig 类。
b、 Spring 容器中尚未注册 FreeMarkerLanguageDriver 类型的 Bean。
@Configuration(proxyBeanMethods = false)@ConditionalOnClass({ FreeMarkerLanguageDriver.class, FreeMarkerLanguageDriverConfig.class })public static class FreeMarkerConfiguration {@Bean@ConditionalOnMissingBeanFreeMarkerLanguageDriver freeMarkerLanguageDriver(FreeMarkerLanguageDriverConfig config) {return new FreeMarkerLanguageDriver(config);}
2 案例:自定义一个自动配置类
- 需求:写一个自动配置类,当访问http://localhost:8080/sayhello时,使用控制器使用自动配置类去打印“HELLO!”
- 创建业务类
public class GreetingService {private String message = "Hello!";public String sayHello() {return message;}// 支持自定义问候语public void setMessage(String message) {this.message = message;}
}
- 创建业务自动配置类
@Configuration
public class GreetingServiceAutoConfiguration {@Beanpublic GreetingService greetingService() {return new GreetingService();}
}
-
注册配置

-
编写控制器
@RestController
public class HelloController {@Autowired private GreetingService service;@RequestMapping("/hello")public String hello(){return "Hello World";}@RequestMapping("/sayhello")public String sayHello(){return service.sayHello();}
}
- 项目结构

- 效果图

相关文章:
Springboot基础篇(4):自动配置原理
1 自动配置原理剖析 1.1 加载配置类的源码追溯 自动配置的触发入口: SpringBootApplication 组合注解是自动配置的起点,其核心包含 EnableAutoConfiguration,该注解使用AutoConfigurationImportSelector 实现配置类的动态加载。 启动类的注…...
Dify 开源大语言模型应用开发平台使用(一)
文章目录 一、创建锂电池专业知识解答应用1.1 应用初始化二、核心功能模块详解2.1 知识库构建2.2 工作流与节点编排节点类型说明工作流设计示例:锂电池选型咨询2.3 变量管理三、测试与调试3.1 单元测试3.2 压力测试3.3 安全验证四、部署与优化建议4.1 部署配置4.2 持续优化结论…...
机器学习深度学习基本概念:logistic regression和softmax
逻辑回归用来处理二分类问题 softmax用来处理多分类问题:比如llm在generate的时候,每个batch里面的一个样本的一个一次generate就是softmax生成一个大小为vocab_size的向量的概率分布,然后再采样 逻辑回归(logistic regression&…...
OpenCV计算摄影学(16)调整图像光照效果函数illuminationChange()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 对选定区域内的梯度场应用适当的非线性变换,然后通过泊松求解器重新积分,可以局部修改图像的表观照明。 cv::illuminati…...
Git - 补充工作中常用的一些命令
Git - 补充工作中常用的一些命令 1 一些场景1.1 场景11.2 场景21.3 场景31.4 场景41.5 场景51.6 场景61.7 场景71.8 场景81.9 场景91.10 场景101.11 场景111.12 场景121.13 场景131.14 场景141.15 场景15 2 git cherry-pick \<commit-hash\> 和 git checkout branch \-\-…...
使用Python的requests库调用API并处理JSON响应的详细步骤
1. 安装request库 pip install requests 2. 发送GET请求 import requests# 定义API地址 url "https://api.example.com/data"# 发送GET请求 response requests.get(url)# 检查HTTP状态码 if response.status_code 200:# 解析JSON响应data response.json()prin…...
Mybatis如何通过databaseId属性支持不同数据库的不同语法
目录 一、前言 二、如何配置 三、源码解读 四、自定义 一、前言 在一次项目功能测试中,发现有个sql在其他嵌入式数据库中执行正常,但是在mysql中执行失败,发现是因为有个字段在mysql中是关键字,需要使用反引号(&…...
android edittext 防止输入多个小数点或负号
有些英文系统的输入法,或者定制输入法。使用xml限制不了输入多个小数点和多个负号。所以代码来控制。 一、通过XML设置限制 <EditTextandroid:id="@+id/editTextNumber"android:layout_width="wrap_content"android:layout_height="wrap_conten…...
windows部署spleeter 版本2.4.0:分离音频的人声和背景音乐
windows部署spleeter 版本2.4.0:分离音频的人声和背景音乐 一、Spleeter 是什么? Spleeter 是由法国音乐流媒体公司 Deezer 开发并开源的一款基于深度学习的音频分离工具。它能够将音乐中的不同音轨(如人声、鼓、贝斯、钢琴等)分…...
深度学习、宽度学习、持续学习与终身学习:全面解析与其在大模型方面的应用
目录 引言: 1. 深度学习(Deep Learning) 1.1 深度学习的基本概念 1.2 深度学习的数学原理 1.3 深度学习的特点 1.4 深度学习在大模型中的应用 2. 宽度学习(Wide Learning) 2.1 宽度学习的基本概念 2.2宽度学习…...
【量化科普】Arbitrage,套利
【量化科普】Arbitrage,套利 🚀量化软件开通 🚀量化实战教程 什么是套利? 套利(Arbitrage)是金融市场中的一种交易策略,指的是在不同市场或不同形式中同时买入和卖出相同或相似的金融产品&a…...
删除已加入 .gitignore却仍被git追踪的文件
.gitignore 文件只会影响未被跟踪的文件,而已经被 Git 跟踪的文件不会因为被添加到 .gitignore 而停止被跟踪。 eg:例如在创建.gitignore文件前,已经将sync.sh文件推送到远程分支,因此该文件已被git追踪。 去掉sync.sh文件追踪的步…...
pytest框架 核心知识的系统复习
1. pytest 介绍 是什么:Python 最流行的单元测试框架之一,支持复杂的功能测试和插件扩展。 优点: 语法简洁(用 assert 替代 self.assertEqual)。 自动发现测试用例。 丰富的插件生态(如失败重试、并发执…...
Spring Cloud Alibaba学习 5- Seata入门使用
Spring Cloud Alibaba学习 5- Seata入门使用 Seata是Spring Cloud Alibaba中用于分布式事务管理的解决方案 一. Seata的基本概念 1. Seata的三大角色 1> TC (Transaction Coordinator) - 事务协调者 维护全局和分支事务的状态,驱动全局事务提交或回滚。TC作…...
WebAssembly技术及应用了解
WebAssembly(Wasm)是一种为Web设计的高效、低级的二进制指令格式,旨在提升Web应用的性能并支持多种编程语言。以下是对其核心概念、优势、应用场景及开发流程的系统介绍: 1. 核心概念 二进制格式:Wasm采用紧凑的二进制…...
Deepseek中的MoE架构的改造:动态可变参数激活的MoE混合专家架构(DVPA-MoE)的考虑
大家好,我是微学AI,今天给大家介绍一下动态可变参数激活MoE架构(Dynamic Variable Parameter-Activated MoE, DVPA-MoE)的架构与实际应用,本架构支持从7B到32B的等多档参数动态激活。该架构通过细粒度难度评估和分层专家路由,实现“小问题用小参数,大问题用大参数”的精…...
NodeJS学习笔记
NodeJS软件安装 node环境安装: https://nodejs.org 安装好后的node通常在C:\Program Files\nodejs验证安装是否成功 node -v npm -v 进入REPL模式命令行模式 nodeNodeJS在REPL模式和编辑器使用 windos在dos下常用命令 windos命令: 1、cmd dos系统2、…...
【交通网络拓扑图实现原理深度解析】
交通网络拓扑图实现原理深度解析 简易demo地址 背景故事:交通网络调度可视化的演进 1. 项目背景 在现代城市轨道交通系统中,交通网络线路的可视化展示一直是一个重要而复杂的问题。传统的交通网络线路图往往采用静态图片方式展示,这种方式…...
【极客时间】浏览器工作原理与实践-2 宏观视角下的浏览器 (6讲) - 2.6 渲染流程(下):HTML、CSS和JavaScript,是如何变成页面的?
https://time.geekbang.org/column/article/118826 2.6 渲染流程(下):HTML、CSS和JavaScript,是如何变成页面的? 2.5介绍了渲染流水线中的 DOM 生成、样式计算和布局三个阶段,2.6讲解渲染流水线后面的阶段…...
NO2.C++语言基础|C++和Java|常量|重载重写重定义|构造函数|强制转换|指针和引用|野指针和悬空指针|const修饰指针|函数指针(C++)
6. C 和 Java 区别(语⾔特性,垃圾回收,应⽤场景等) 指针: Java 语⾔让程序员没法找到指针来直接访问内存,没有指针的概念,并有内存的⾃动管理功能,从⽽有效的防⽌了 C 语⾔中的指针…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...
《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...
