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

SpringBoot核心原理深度剖析:自动配置是如何实现的?

SpringBoot核心原理深度剖析:自动配置是如何实现的?

    • 前言
    • 一、什么是自动配置?
    • 二、自动配置的入口:`@SpringBootApplication`
    • 三、`@EnableAutoConfiguration` 做了什么?
    • 四、`AutoConfigurationImportSelector` 核心流程
    • 五、`getAutoConfigurationEntry` 核心逻辑
    • 六、从哪里加载候选配置类?
    • 七、自动配置的核心:条件注解
    • 八、完整流程图
    • 九、实战:手写一个自定义 Starter
    • 十、常见问题与总结
      • Q1:自动配置类什么时候不生效?
      • Q2:如何查看当前哪些自动配置生效?
      • Q3:如何覆盖自动配置?
    • 总结

🌺The Begin🌺点点关注,收藏不迷路🌺

⬇ ⬇ 底部 ⬇ ⬇

前言

用过 SpringBoot 的同学都知道,它最大的特点就是“约定大于配置”。我们只需要引入一个starter,几乎不用写任何配置,就能直接使用 Redis、MongoDB、JDBC、RabbitMQ 等各种中间件。这一切的背后,正是 SpringBoot 的自动配置机制。

那么问题来了:SpringBoot 到底是怎么做到自动配置的?它的底层原理是什么?

今天这篇文章,我会带大家手撕源码 + 流程图 + 案例,彻底搞懂 SpringBoot 自动配置的底层实现。


一、什么是自动配置?

简单说:自动配置 = 根据类路径下的依赖 + 配置文件条件,自动创建并注册对应的 Bean。

比如:

  • 引入spring-boot-starter-data-redis→ 自动创建RedisTemplate
  • 引入spring-boot-starter-web→ 自动配置DispatcherServletTomcatJackson

不需要@EnableXXX,不需要手动写@Bean


二、自动配置的入口:@SpringBootApplication

我们知道,启动类上都会加这个注解:

@SpringBootApplicationpublicclassDemoApplication{publicstaticvoidmain(String[]args){SpringApplication.run(DemoApplication.class,args);}}

点进去看源码:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration// 关键!@ComponentScanpublic@interfaceSpringBootApplication{}

核心就是@EnableAutoConfiguration


三、@EnableAutoConfiguration做了什么?

再点进去:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)// 关键!public@interfaceEnableAutoConfiguration{}

这里通过@Import引入了AutoConfigurationImportSelector,它是自动配置的真正实现者


四、AutoConfigurationImportSelector核心流程

AutoConfigurationImportSelector实现了ImportSelector接口,其核心方法是:

@OverridepublicString[]selectImports(AnnotationMetadataannotationMetadata){// 判断是否开启自动配置if(!isEnabled(annotationMetadata)){returnNO_IMPORTS;}// 获取所有自动配置类的全限定名AutoConfigurationEntryautoConfigurationEntry=getAutoConfigurationEntry(annotationMetadata);returnStringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}

五、getAutoConfigurationEntry核心逻辑

这个方法做了几件事:

  1. 获取@EnableAutoConfiguration的排除项(exclude)
  2. META-INF/spring.factoriesMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports中加载候选配置类
  3. 过滤掉排除项
  4. 去重、排序
  5. 返回最终要加载的配置类
protectedAutoConfigurationEntrygetAutoConfigurationEntry(AnnotationMetadataannotationMetadata){// 1. 获取 exclude 列表Set<String>exclusions=getExclusions(annotationMetadata);// 2. 加载所有候选配置类List<String>configurations=getCandidateConfigurations(annotationMetadata);// 3. 移除 exclude 的configurations.removeAll(exclusions);// 4. 过滤(比如条件注解)configurations=filter(configurations);returnnewAutoConfigurationEntry(configurations,exclusions);}

六、从哪里加载候选配置类?

核心方法getCandidateConfigurations

protectedList<String>getCandidateConfigurations(AnnotationMetadatametadata,AnnotationAttributesattributes){List<String>configurations=SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader());returnconfigurations;}

loadFactoryNames会扫描所有 jar 包下的META-INF/spring.factories文件,key =EnableAutoConfiguration对应的配置类。

示例(spring-boot-autoconfigure 包中的部分内容):

# 文件:META-INF/spring.factories org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ ...

注意:SpringBoot 2.7 之后部分配置迁移到META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports


七、自动配置的核心:条件注解

自动配置类并不会无条件加载,而是通过@Conditional系列注解控制。

举例:DataSourceAutoConfiguration

@Configuration(proxyBeanMethods=false)@ConditionalOnClass({DataSource.class,EmbeddedDatabaseType.class})@ConditionalOnMissingBean(type="io.r2dbc.spi.ConnectionFactory")@EnableConfigurationProperties(DataSourceProperties.class)@Import(DataSourcePoolMetadataProvidersConfiguration.class)publicclassDataSourceAutoConfiguration{// ...}

常见条件注解:

注解作用
@ConditionalOnClass类路径下存在某类才生效
@ConditionalOnMissingBean容器中无某 Bean 才生效
@ConditionalOnProperty配置文件中存在某属性才生效
@ConditionalOnWebApplication是 Web 环境才生效

这就是为什么你配了spring.datasource.url,自动配置才会创建DataSource


八、完整流程图

+-----------------------------------+ | 启动类 @SpringBootApplication | +-----------------------------------+ | v +-----------------------------------+ | @EnableAutoConfiguration | +-----------------------------------+ | v +-----------------------------------+ | AutoConfigurationImportSelector | +-----------------------------------+ | v +-----------------------------------+ | getAutoConfigurationEntry | | - 获取 exclude | | - 加载 META-INF/spring.factories | | - 过滤 exclude | | - @Conditional 过滤 | +-----------------------------------+ | v +-----------------------------------+ | 加载自动配置类 (如 RedisAutoConf) | +-----------------------------------+ | v +-----------------------------------+ | 条件注解检查 (@ConditionalOnXX) | | - 存在类? | | - 存在配置? | | - 存在 Bean? | +-----------------------------------+ | v +-----------------------------------+ | 创建并注册相应的 Bean 到容器 | +-----------------------------------+

九、实战:手写一个自定义 Starter

  1. 创建自动配置类
@Configuration@ConditionalOnClass(HelloService.class)@EnableConfigurationProperties(HelloProperties.class)publicclassHelloAutoConfiguration{@Bean@ConditionalOnMissingBeanpublicHelloServicehelloService(HelloPropertiesproperties){returnnewHelloService(properties);}}
  1. 编写配置属性类
@ConfigurationProperties(prefix="hello")publicclassHelloProperties{privateStringname="world";privateStringmsg="hello";// getter/setter}
  1. META-INF/spring.factories中注册
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.starter.HelloAutoConfiguration

这样别人引入你的 starter 后,只要配置hello.name=xxxHelloService就会自动注入容器。


十、常见问题与总结

Q1:自动配置类什么时候不生效?

  • 被 exclude 手动排除
  • 条件注解不满足(类不存在 / 属性未配置 / Bean 已存在)

Q2:如何查看当前哪些自动配置生效?

启动时加--debug,可以看到:

Positive matches: DataSourceAutoConfiguration matched Negative matches: RedisAutoConfiguration: missing required class org.springframework.data.redis.core.RedisOperations

Q3:如何覆盖自动配置?

  • 自己定义同名的@Bean
  • 使用spring.autoconfigure.exclude排除
  • 修改配置属性(如spring.datasource.url

总结

SpringBoot 自动配置的本质:

  1. 入口@EnableAutoConfiguration
  2. 加载器AutoConfigurationImportSelector
  3. 配置来源META-INF/spring.factoriesAutoConfiguration.imports
  4. 生效控制@Conditional系列条件注解
  5. 属性绑定@ConfigurationProperties+@EnableConfigurationProperties

理解了这个流程,你就能:

  • 快速定位 Bean 为什么生效 / 不生效
  • 自定义自己的 Starter
  • 看懂 SpringBoot 源码的核心脉络

希望这篇文章能帮你真正搞懂 SpringBoot 自动配置的原理。如果觉得有收获,欢迎点赞 + 收藏 + 评论交流!


🌺The End🌺点点关注,收藏不迷路🌺

⬆ ⬆ 顶部 ⬆ ⬆
http://www.rkmt.cn/news/1436030.html

相关文章:

  • 引导流程漏斗崩塌预警,深度拆解Gemini前30秒用户流失的5大技术归因与实时拦截方案
  • RevokeMsgPatcher:让撤回的消息无处可藏!Windows微信QQ防撤回终极指南
  • 雀魂MAX终极指南:一键解锁完整角色装扮的完整解决方案
  • 北京除甲醛公司优劣评判标准及直营加盟模式深度解析 - 资讯纵览
  • 当大模型“说错话”已成常态——Gemini级危机的7层防御体系(含实时语义熔断机制设计图)
  • 给你的Windows系统来一次彻底“瘦身“:Win11Debloat系统优化工具完全指南
  • 从达芬奇透视法到Web3生成艺术:技术驱动艺术演进的底层逻辑与实践
  • 具身智能的先锋:物理世界中的机器人如何依赖 Agent 架构
  • Gemini信用模型上线即失效?——97%机构忽略的3类时序特征泄露漏洞(含TensorFlow Lite边缘部署补丁)
  • 第4章:Codex CLI基础操作
  • 视频怎么在线去水印:全场景实操方法与免费工具精选推荐
  • 2026年工业燃烧机/低氮燃烧器/燃气燃烧机最新推荐榜单:正英、天时等品牌稳定性与节能改造深度解析 - 品牌企业推荐师(官方)
  • 基于Micro:bit与加速度计的宠物行为追踪器设计与实现
  • 3分钟掌握!九大网盘直链解析工具LinkSwift完全指南
  • WarcraftHelper:让经典魔兽争霸III在现代电脑上重焕新生
  • Gemini模型冷启动失败率高达68%?揭秘3个未公开的特征工程预埋点与7天快速校准SOP
  • 如何永久保存微信聊天记录:3个颠覆性功能让你重新掌控数字记忆
  • 2026实测10款AI智能降重工具红黑榜!优缺点无保留曝光,达标率对标顶级水准 - 降AI小能手
  • 不會Python还想做工具?AI這波真的讓普通人也能DIY了
  • 2026年吸料机厂家推荐排行榜:全自动/真空/塑料/免清理/节能/一体式吸料机源头工厂精选,专业实力与品质口碑深度解析 - 品牌企业推荐师(官方)
  • 如何快速掌握开源电机控制器:ODrive高性能控制完全指南
  • 2026湖南GEO服务商专业实力测评与选型参考报告 - 湖南格讯
  • Python微信机器人终极指南:5分钟构建智能自动化助手
  • 如何快速将iPad变成Linux虚拟副屏:终极免费解决方案
  • 【电力装备制造业智能化转型】【数据基础设施篇】【1】客户既有数据源的接入策略
  • 2026年选择江苏GEO优化代理公司避坑指南:洞察杭州市场,选对本土源头服务商 - 品牌报告
  • 郑州市 登封市 甲醛检测、甲醛清除|维小达 甲醛CMA检测、新房甲醛清除、工装空气治理、异味根除、苯系物TVOC综合治理一站式服务 - 维小达科技
  • 2026年10款论文降AIGC工具亲测:从90%降至10%的宝藏之选
  • 汕头奢侈品回收市场2026指南:潮奢汇汕头店领衔合规服务,4家靠谱机构推荐+避坑攻略 - 小仙贝贝
  • 郑州市 新郑市 甲醛检测、甲醛清除|维小达 甲醛CMA检测、新房甲醛清除、工装空气治理、异味根除、苯系物TVOC综合治理一站式服务 - 维小达科技