跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

SpringBoot 核心原理:配置优先级、Bean 管理与自动配置

SpringBoot 项目支持 properties、yml、yaml 三种配置文件,推荐统一使用 yml 格式。IOC 容器默认 Bean 为单例,可通过@Scope 配置作用域,单例 Bean 默认启动时实例化,有状态 Bean 需注意线程安全问题。第三方依赖提供的 Bean 需通过@Configuration 和@Bean 注解声明。SpringBoot 起步依赖利用 Maven 传递性简化依赖引入。自动配置核心在于@EnableAutoConfiguration 结合@Import 加载 META-INF 下的配置类,并通过@Conditional 按需装配 Bean。自定义 Starter 可封装公共组件,简化多项目中的技术整合流程。

星辰大海发布于 2026/4/7更新于 2026/5/2417 浏览

1 配置优先级

SpringBoot 项目当中支持的三类配置文件:

  • application.properties
  • application.yml
  • application.yaml

**配置文件优先级排名(从高到低):**properties 配置文件 > yml 配置文件 > yaml 配置文件

虽然 springboot 支持多种格式配置文件,但是在项目开发时,推荐统一使用一种格式的配置。(yml 是主流)

2 Bean 的管理

2.1 Bean 的作用域

IOC 容器当中,默认 bean 对象是单例的 (只有一个实例对象),可以借助 Spring 中的@Scope 注解来进行配置作用域。

作用域说明
singleton容器内同名称的 bean 只有一个实例(单例)(默认)
prototype每次使用该 bean 时会创建新的实例(非单例)

文章配图

  • 默认 singleton 的 bean,在容器启动时被创建,可以使用@Lazy 注解来延迟初始化(延迟到第一次使用时)
  • prototype 的 bean,每一次使用该 bean 的时候都会创建一个新的实例。
  • 实际开发当中,绝大部分的 bean 是单例的,也就是说绝大部分 bean 不需要配置 scope 属性。

**面试题 1:Spring 容器的 bean 是单例的还是多例的?单例的 bean 是什么时候实例化的?**默认是单例的单例的 bean,默认是项目启动时实例化的(通过 @Lazy 可以延迟初始化)

面试题 2:Spring 容器的 bean 是线程安全的吗?bean 的线程安全取决于 bean 的状态及 bean 的作用域单例 bean:如果是无状态的 bean,内部不保存任何状态信息,则是线程安全的。单例 bean:如果是有状态的 bean,内部会保存状态信息,多个线程会同时操作该 bean 时,可能会出现数据不一致的问题,这样的 bean 则是线程不安全的。

2.2 第三方 Bean

之前我们所配置的 bean,像 controller、service,dao 三层体系下编写的类,这些类都是我们在项目当中自己定义的类 (自定义类)。当我们要声明这些 bean,也非常简单,我们只需要在类上加上@Component以及它的这三个衍生注解(@Controller、@Service、@Repository),就可以来声明这个 bean 对象了。

但是在我们项目开发当中,还有一种情况就是这个类它不是我们自己编写的,而是我们引入的第三方依赖当中提供的,那么此时我们是无法使用 @Component 及其衍生注解来声明 bean 的,此时就需要使用**@Bean**注解来声明 bean 了。

若要管理的第三方 bean 对象,建议对这些 bean 进行集中分类配置,可以通过 @Configuration 注解声明一个配置类。【推荐】

package com.example.config;
import com.example.utils.AliyunOSSOperator;
import com.example.utils.AliyunOSSProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class OSSConfig {
    @Bean
    public AliyunOSSOperator aliyunOSSOperator(AliyunOSSProperties ossProperties) {
        return new AliyunOSSOperator(ossProperties);
    }
}

3 SpringBoot 原理

3.1 起步依赖

起步依赖的原理就是 Maven 的依赖传递。

  • 在 SpringBoot 给我们提供的这些起步依赖当中,已提供了当前程序开发所需要的所有的常见依赖 (官网地址:https://docs.spring.io/spring-boot/docs/2.7.7/reference/htmlsingle/#using.build-systems.starters)。
  • 比如:springboot-starter-web,这是 web 开发的起步依赖,在 web 开发的起步依赖当中,就集成了 web 开发中常见的依赖:json、web、webmvc、tomcat 等。我们只需要引入这一个起步依赖,其他的依赖都会自动的通过 Maven 的依赖传递进来。

3.2 自动配置

3.2.1 实现方案

方案一:思考:引入进来的第三方依赖当中的 bean 以及配置类为什么没有生效?

  • 原因在我们之前讲解 IOC 的时候有提到过,在类上添加@Component 注解来声明 bean 对象时,还需要保证@Component 注解能被 Spring 的组件扫描到。
  • SpringBoot 项目中启动类的@SpringBootApplication 注解,具有包扫描的作用,但是它只会扫描启动类所在的当前包以及子包。
  • 当前包:com.example,第三方依赖中提供的包:com.example(扫描不到)

那么如何解决以上问题的呢?

  • 方案 1:@ComponentScan 组件扫描(繁琐、性能低)
  • 方案 2:@Import 导入(使用@Import 导入的类会被 Spring 加载到 IOC 容器中)

方案二:@Import 导入,主要有以下几种:

  • 导入普通类
  • 导入配置类
  • 导入 ImportSelector 接口实现类

如果基于以上方式完成自动配置,当要引入一个第三方依赖时,是不是还要知道第三方依赖中有哪些配置类和哪些 Bean 对象?答案:是的。(对程序员来讲,很不友好,而且比较繁琐)

结论:我们不用自己指定要导入哪些 bean 对象和配置类了,让第三方依赖它自己来指定。

怎么让第三方依赖自己指定 bean 对象和配置类?

答案:比较常见的方案就是第三方依赖给我们提供一个注解,这个注解一般都以@EnableXxxx 开头的注解,注解中封装的就是@Import 注解

  • 使用第三方依赖提供的 @EnableXxxxx 注解(方便 优雅)
3.2.2 原理分析

文章配图

在@SpringBootApplication 注解中包含了:

1.元注解(不再解释)

2.@SpringBootConfiguration

该改注解上使用了@Configuration,表明 SpringBoot 启动类就是一个配置类。

3.@EnableAutoConfiguration**(自动配置核心注解)**

  • 封装了**@Import 注解**(Import 注解中指定了一个 ImportSelector 接口的实现类)。
  • 在实现类重写的 selectImports() 方法,读取当前项目下所有依赖 jar 包中 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 两个文件里面定义的配置类(配置类中定义了@Bean 注解标识的方法)。
  • 当 SpringBoot 程序启动时,就会加载配置文件当中所定义的配置类,并将这些配置类信息 (类的全限定名) 封装到 String 类型的数组中,最终通过@Import 注解将这些配置类全部加载到 Spring 的 IOC 容器中,交给 IOC 容器管理。

4.@ComponentScan

用来进行组件扫描的,扫描启动类所在的包及其子包下所有被@Component 及其衍生注解声明的类。

问题:在 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中定义的配置类非常多,而且每个配置类中又可以定义很多的 bean,那这些 bean 都会注册到 Spring 的 IOC 容器中吗? 答案:并不是。在声明 bean 对象时,上面有加一个以 @Conditional 开头的注解,这种注解的作用就是按照条件进行装配,只有满足条件之后,才会将 bean 注册到 Spring 的 IOC 容器中。

3.2.3 自定义 starter

所谓 starter 指的就是 SpringBoot 当中的起步依赖。在 SpringBoot 当中已经给我们提供了很多的起步依赖了,我们为什么还需要自定义 starter 起步依赖?

这是因为在实际的项目开发当中,我们可能会用到很多第三方的技术,并不是所有的第三方的技术官方都给我们提供了与 SpringBoot 整合的 starter 起步依赖,但是这些技术又非常的通用,在很多项目组当中都在使用。

业务场景:

  • 我们前面案例当中所使用的阿里云 OSS 对象存储服务,现在阿里云的官方是没有给我们提供对应的起步依赖的,这个时候使用起来就会比较繁琐,我们需要引入对应的依赖。我们还需要在配置文件当中进行配置,还需要基于官方 SDK 示例来改造对应的工具类,我们在项目当中才可以进行使用。
  • 大家想在我们当前项目当中使用了阿里云 OSS,我们需要进行这么多步的操作。在别的项目组当中要想使用阿里云 OSS,是不是也需要进行这么多步的操作,所以这个时候我们就可以自定义一些公共组件,在这些公共组件当中,我就可以提前把需要配置的 bean 都提前配置好。将来在项目当中,我要想使用这个技术,我直接将组件对应的坐标直接引入进来,就已经自动配置好了,就可以直接使用了。我们也可以把公共组件提供给别的项目组进行使用,这样就可以大大的简化我们的开发。

在 SpringBoot 项目中,一般都会将这些公共组件封装为 SpringBoot 当中的 starter,也就是我们所说的起步依赖。

而在 springboot 中,官方提供的起步依赖 或 第三方提供的起步依赖,基本都会包含两个模块,如下所示:

文章配图

其中,spring-boot-starter 或 xxx-spring-boot-starter 这个模块主要是依赖管理的功能。而 spring-boot-autoconfigure 或 xxxx-spring-boot-autoconfigure 主要是起到自动配置的作用,自动配置的核心代码就在这个模块中编写。

SpringBoot 官方 starter 命名: spring-boot-starter-xxxx

第三组织提供的 starter 命名: xxxx-spring-boot-starter

而自动配置模块的核心,就是编写自动配置的核心代码,然后将自动配置的核心类,配置在核心的配置文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 中。

目录

  1. 1 配置优先级
  2. 2 Bean 的管理
  3. 2.1 Bean 的作用域
  4. 2.2 第三方 Bean
  5. 3 SpringBoot 原理
  6. 3.1 起步依赖
  7. 3.2 自动配置
  8. 3.2.1 实现方案
  9. 3.2.2 原理分析
  10. 3.2.3 自定义 starter
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 纯 CSS 实现双半圆进度条:拒绝 JS 也能丝滑动画
  • Python IDLE 使用指南:掌握 Python 自带集成开发环境
  • VSCode 中 GitHub Copilot 插件无模型选项的解决方案
  • OpenClaw 快速部署指南:免环境配置十分钟跑通 AI 助理
  • Qwen3-4B-Instruct 模型快速部署与 AI 写作应用指南
  • Python 字典查询高效的底层原理
  • 渗透测试基础概念与流程详解
  • Python IDLE 使用教程:快速上手自带集成开发环境
  • ToDesk 顺网云 海马云部署 DeepSeek 大模型对比评测
  • Linux 一切皆文件:深入理解文件与文件 IO
  • Python IDLE 使用指南:Python 自带集成开发环境入门
  • 宇树 G1 人形机器人 VR 遥操与 IL 开发:从 xr_teleoperate 到 unitree_IL_lerobot
  • Python 3 爬虫、数据清洗与可视化实战
  • Claude Code 安装配置与项目实战指南
  • PP-DocLayoutV3 WebUI 自定义 CSS 注入与企业 UI 规范适配
  • Linux 信号机制:键盘输入与系统调用产生
  • 英伟达 GTC 2025 医疗健康与生命科学会议要点解析
  • 数据结构基础:栈与队列的顺序及链式实现
  • 基于 GOT-OCR2.0 与 Qwen2.5-Math 构建 AI 数学辅导系统
  • 三款主流云电脑部署 DeepSeek 模型性能实测对比

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online