news 2026/3/23 4:21:07

SpringBoot自动装配原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot自动装配原理

一、核心认知

1.1 定义

SpringBoot自动装配是SpringBoot的核心特性,指应用启动时,SpringBoot会根据项目引入的依赖(jar包)、配置文件信息,自动识别并加载符合条件的配置类,将配置类中的Bean自动注册到Spring容器中,无需开发者手动编写大量XML或Java配置代码,实现“开箱即用”。

1.2 核心价值

  • 简化配置:替代传统Spring的繁琐手动配置,降低开发成本

  • 约定优于配置:遵循默认约定,开发者只需关注业务逻辑,无需关注框架底层配置

  • 灵活性高:支持自定义配置覆盖默认配置,兼顾便捷性与扩展性

1.3 核心关键词

@EnableAutoConfiguration(自动装配开关)、自动配置类(xxxAutoConfiguration)、条件注解(@ConditionalOnXXX)、SPI机制(配置类加载)、BeanDefinitionRegistry(Bean注册中心)

二、自动装配全流程拆解(源码级逻辑)

核心流程:触发自动装配 → 加载候选配置类 → 条件筛选生效配置类 → 注册Bean到容器

阶段1:触发自动装配(入口:@SpringBootApplication)

1.1 入口注解关系

@SpringBootApplication是组合注解,核心功能由@EnableAutoConfiguration实现,三者关系如下:

@SpringBootApplication = @SpringBootConfiguration + @ComponentScan + @EnableAutoConfiguration

  • @SpringBootConfiguration:本质是@Configuration,标识当前类是Spring配置类,可通过@Bean声明自定义Bean

  • @ComponentScan:扫描当前类所在包及其子包下的@Component、@Service、@Controller、@Repository注解类,自动注册为Bean

  • @EnableAutoConfiguration:自动装配的核心开关,触发后续配置类加载、筛选逻辑

1.2 @EnableAutoConfiguration源码核心逻辑

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage // 标记自动配置的基础包(默认是启动类所在包) @Import(AutoConfigurationImportSelector.class) // 核心:导入配置类选择器 public @interface EnableAutoConfiguration { // 手动排除不需要的自动配置类 Class<?>[] exclude() default {}; // 通过类名排除自动配置类(全类名字符串) String[] excludeName() default {}; }

关键核心:@Import(AutoConfigurationImportSelector.class)

AutoConfigurationImportSelector是自动装配的“总调度器”,负责加载候选自动配置类、过滤配置类,是连接“触发”与“加载”的关键桥梁。

阶段2:加载候选自动配置类(SPI机制)

2.1 核心原理:SPI机制

SPI(Service Provider Interface)是Java的服务发现机制,SpringBoot基于SPI扩展,通过固定路径的配置文件加载候选自动配置类。

注意:SpringBoot 2.7+版本使用META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件(替代旧版的META-INF/spring.factories)。

2.2 AutoConfigurationImportSelector核心方法:selectImports()

该方法是加载候选配置类的核心入口,执行流程如下:

public class AutoConfigurationImportSelector implements DeferredImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { // 1. 判断自动装配是否开启(默认开启) if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; // 不加载任何配置类 } // 2. 加载并处理候选自动配置类 AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata); // 3. 返回最终要加载的配置类全类名数组 return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); } // 核心逻辑:获取候选配置类并过滤 protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { // 解析@EnableAutoConfiguration的属性(如exclude) AnnotationAttributes attributes = getAttributes(annotationMetadata); // 步骤1:加载AutoConfiguration.imports中的所有候选配置类 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); // 步骤2:去重(避免同一配置类被多次加载) configurations = removeDuplicates(configurations); // 步骤3:排除指定的配置类(根据@EnableAutoConfiguration的exclude属性) Set<String> exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); // 步骤4:通过SpringFactoriesLoader加载的过滤器进一步筛选(可选,底层扩展用) configurations = getConfigurationClassFilter().filter(configurations); // 步骤5:触发自动配置导入事件(供监听器感知) fireAutoConfigurationImportEvents(configurations, exclusions); // 返回处理后的配置类列表和排除列表 return new AutoConfigurationEntry(configurations, exclusions); } }

2.3 候选配置类来源

getCandidateConfigurations()方法会通过Spring的SpringFactoriesLoader工具类,读取META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中的内容。

该文件是SpringBoot内置的配置文件,包含约100+个自动配置类的全类名,例如:

  • org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration(Web开发配置)

  • org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration(数据源配置)

  • org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration(Redis配置)

阶段3:条件筛选(核心:只加载符合条件的配置类)

加载候选配置类后,SpringBoot不会无脑加载所有类,而是通过“条件注解”判断是否符合当前应用环境,只有满足条件的配置类才会被最终加载。

3.1 核心条件注解(常用)

注解

对应Condition实现类

作用

典型场景

@ConditionalOnClass

OnClassCondition

类路径下存在指定类时生效

引入spring-boot-starter-web后,类路径存在DispatcherServlet.class,WebMvcAutoConfiguration才生效

@ConditionalOnMissingClass

OnClassCondition

类路径下不存在指定类时生效

未引入Redis依赖时,某些默认缓存配置生效

@ConditionalOnBean

OnBeanCondition

Spring容器中存在指定Bean时生效

存在DataSource Bean时,MyBatis的SqlSessionFactory配置生效

@ConditionalOnMissingBean

OnBeanCondition

Spring容器中不存在指定Bean时生效

开发者未自定义DataSource时,加载默认数据源配置

@ConditionalOnProperty

OnPropertyCondition

配置文件中存在指定属性(且值匹配)时生效

配置spring.redis.enabled=true时,RedisAutoConfiguration生效

@ConditionalOnWebApplication

OnWebApplicationCondition

当前应用是Web应用(Servlet/Reactive)时生效

WebMvcAutoConfiguration仅在Web应用中生效

@ConditionalOnNotWebApplication

OnWebApplicationCondition

当前应用不是Web应用时生效

某些非Web环境的缓存配置

3.2 筛选原理

  • 所有条件注解都基于Spring的Condition接口实现,该接口有一个matches()方法,返回true表示满足条件,配置类可加载;返回false则不加载。

  • Spring在解析配置类时,会先执行对应Condition的matches()方法,进行条件判断,再决定是否解析该配置类。

3.3 示例:WebMvcAutoConfiguration的条件筛选

// 条件1:类路径存在Servlet和DispatcherServlet(引入web依赖后才满足) @ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) // 条件2:当前是Servlet类型的Web应用(而非Reactive Web应用) @ConditionalOnWebApplication(type = Type.SERVLET) // 条件3:配置文件中spring.mvc.enabled=true(默认true,可省略) @ConditionalOnProperty(prefix = "spring.mvc", name = "enabled", havingValue = "true", matchIfMissing = true) // 标识为配置类 @Configuration // 导入必要的Bean依赖 @Import(EnableWebMvcConfiguration.class) public class WebMvcAutoConfiguration { // 条件4:容器中不存在DispatcherServlet时,才自动注册默认的DispatcherServlet @Bean @ConditionalOnMissingBean public DispatcherServlet dispatcherServlet(WebMvcProperties webMvcProperties) { DispatcherServlet dispatcherServlet = new DispatcherServlet(); dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest()); return dispatcherServlet; } }

只有同时满足前3个类级别的条件,WebMvcAutoConfiguration才会被加载;只有满足条件4,才会自动注册默认的DispatcherServlet(若开发者自定义了DispatcherServlet,默认配置会失效)。

阶段4:注册Bean到Spring容器

4.1 配置类解析

经过条件筛选后的生效配置类,会被Spring的ConfigurationClassPostProcessor(配置类后置处理器)解析。该处理器是Spring的BeanFactoryPostProcessor,负责解析@Configuration类、@Bean注解等。

4.2 Bean注册流程

  1. 解析配置类中的@Bean注解,将每个@Bean方法封装为BeanDefinition(Bean定义信息,包含Bean的类型、作用域、依赖等)。

  2. 将BeanDefinition注册到Spring的BeanDefinitionRegistry(Bean定义注册中心)。

  3. Spring容器启动的后续阶段(实例化阶段),会根据BeanDefinition的信息,创建Bean实例并初始化,最终将Bean放入容器中供开发者使用。

三、自动装配完整流程可视化

graph TD A[启动SpringBoot应用] --> B[执行SpringApplication.run()] B --> C[解析@SpringBootApplication注解] C --> D[触发@EnableAutoConfiguration] D --> E[AutoConfigurationImportSelector.selectImports()] E --> F[加载META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports] F --> G[获取候选自动配置类列表] G --> H[去重、排除指定配置类] H --> I[通过@ConditionalOnXXX注解筛选生效配置类] I --> J[ConfigurationClassPostProcessor解析生效配置类] J --> K[解析@Bean注解,生成BeanDefinition] K --> L[将BeanDefinition注册到BeanDefinitionRegistry] L --> M[容器实例化Bean并初始化] M --> N[应用启动完成,Bean可直接使用]

四、关键细节与核心原则

4.1 核心原则:约定优于配置,自定义优先

  • 约定优于配置:默认的配置类路径、Bean命名、配置文件位置等都遵循SpringBoot的约定,无需手动指定。

  • 自定义优先:开发者自定义的Bean会覆盖自动配置的Bean(核心原因是@ConditionalOnMissingBean注解);自定义配置文件的属性会覆盖自动配置的默认属性。

4.2 自动配置类的加载时机

自动配置类通过AutoConfigurationImportSelector加载,该类实现了DeferredImportSelector(延迟导入选择器),意味着自动配置类会在开发者自定义的配置类、业务Bean加载完成之前加载。

目的:确保自动配置的默认Bean先就绪,同时允许开发者后续通过自定义Bean覆盖默认配置。

4.3 手动关闭/排除自动配置类的两种方式

方式1:通过@SpringBootApplication的exclude属性(代码级)

// 排除数据源自动配置类(适用于不需要数据源的场景) @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }

方式2:通过配置文件(配置级,更灵活)

# 单个排除 spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration # 多个排除(用逗号分隔) spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration

4.4 自定义自动装配(实现自己的Starter)

如果需要开发通用组件供其他项目复用,可自定义Starter,实现自动装配,核心步骤:

  1. 创建Maven/Gradle项目,命名遵循规范:xxx-spring-boot-starter(如mybatis-spring-boot-starter)。

  2. 编写自动配置类(XXXAutoConfiguration),用@Configuration+条件注解声明Bean。

  3. 在项目resources目录下创建META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,写入自动配置类的全类名。

  4. (可选)编写配置属性类(XXXProperties),通过@ConfigurationProperties绑定配置文件中的属性。

  5. 打包发布,其他项目引入该Starter后,即可自动加载配置类中的Bean。

五、实战验证:查看生效的自动配置类

开发中可通过开启debug日志,直观查看自动配置类的加载情况,步骤:

5.1 开启debug模式

在application.properties/application.yml中添加配置:

# 开启debug日志,打印自动配置类加载详情 debug=true

5.2 查看控制台输出

启动项目后,控制台会输出3类关键信息:

  • Positive matches:生效的自动配置类(符合条件,已加载)

  • Negative matches:未生效的自动配置类(不符合条件,未加载,会说明未生效原因)

  • Exclusions:手动排除的自动配置类

示例输出(片段):

============================ CONDITIONS EVALUATION REPORT ============================ Positive matches: ----------------- WebMvcAutoConfiguration matched: - @ConditionalOnClass found required classes 'javax.servlet.Servlet', 'org.springframework.web.servlet.DispatcherServlet' (OnClassCondition) - @ConditionalOnWebApplication(type = SERVLET) matched (OnWebApplicationCondition) - @ConditionalOnProperty (spring.mvc.enabled=true) matched (OnPropertyCondition) Negative matches: ----------------- RedisAutoConfiguration: Did not match: - @ConditionalOnClass did not find required class 'org.springframework.data.redis.core.RedisOperations' (OnClassCondition) Exclusions: ----------- None

六、总结

6.1 核心逻辑梳理

SpringBoot自动装配的核心是“触发-加载-筛选-注册”四步走:

  1. 触发:@SpringBootApplication中的@EnableAutoConfiguration开启自动装配

  2. 加载:AutoConfigurationImportSelector通过SPI机制加载AutoConfiguration.imports中的候选配置类

  3. 筛选:通过@ConditionalOnXXX注解根据依赖、配置、容器状态筛选生效配置类

  4. 注册:Spring解析生效配置类的@Bean注解,将Bean注册到容器中

6.2 关键要点回顾

  • 入口:@EnableAutoConfiguration + AutoConfigurationImportSelector

  • 配置类来源:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

  • 筛选核心:@ConditionalOnXXX注解(基于Condition接口)

  • 核心原则:约定优于配置,自定义Bean > 自动配置Bean

  • 验证方式:开启debug日志查看条件评估报告

6.3 学习价值

理解自动装配原理,不仅能解决开发中“为什么引入依赖就自动生效”“为什么自定义配置不生效”等问题,还能帮助我们更好地扩展SpringBoot(如自定义Starter),深入掌握Spring容器的Bean加载机制。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/13 13:29:48

空洞骑士模组管理器Scarab:从零开始的完整使用手册

空洞骑士模组管理器Scarab&#xff1a;从零开始的完整使用手册 【免费下载链接】Scarab An installer for Hollow Knight mods written in Avalonia. 项目地址: https://gitcode.com/gh_mirrors/sc/Scarab 还在为空洞骑士模组安装的繁琐步骤而头疼吗&#xff1f;Scarab模…

作者头像 李华
网站建设 2026/3/20 23:00:54

Win11Debloat终极指南:让你的Windows系统飞起来

Win11Debloat终极指南&#xff1a;让你的Windows系统飞起来 【免费下载链接】Win11Debloat 一个简单的PowerShell脚本&#xff0c;用于从Windows中移除预装的无用软件&#xff0c;禁用遥测&#xff0c;从Windows搜索中移除Bing&#xff0c;以及执行各种其他更改以简化和改善你的…

作者头像 李华
网站建设 2026/3/14 17:51:58

C语言--自定义类型(联合和枚举)

1.联合体a.联合体类型的声明像结构体⼀样&#xff0c;联合体也是由⼀个或者多个成员构成&#xff0c;这些成员可以不同的类型。 但是编译器只为最⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间。所 以联合体也叫&#xff1a;共⽤体。 给联合体其中⼀个…

作者头像 李华
网站建设 2026/3/16 16:05:40

深度学习毕设项目:基于python-CNN卷积神经网络的鱼类识别

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/3/17 6:27:30

番茄小说下载器:离线阅读的革命性解决方案

番茄小说下载器&#xff1a;离线阅读的革命性解决方案 【免费下载链接】Tomato-Novel-Downloader 番茄小说下载器不精简版 项目地址: https://gitcode.com/gh_mirrors/to/Tomato-Novel-Downloader 还在为网络信号时断时续而无法畅享阅读乐趣而困扰吗&#xff1f;番茄小说…

作者头像 李华
网站建设 2026/3/13 20:07:44

如何用Zoplicate插件彻底告别文献管理烦恼?

如何用Zoplicate插件彻底告别文献管理烦恼&#xff1f; 【免费下载链接】zoplicate A plugin that does one thing only: Detect and manage duplicate items in Zotero. 项目地址: https://gitcode.com/gh_mirrors/zo/zoplicate 文献管理最让人头疼的是什么&#xff1f…

作者头像 李华