SpringBoot YAML 配置读取机制 + 数据库自动初始化原理

👨‍💻程序员三明治个人主页
🔥 个人专栏 : 《设计模式精解》 《重学数据结构》

🤞先做到 再看见!


目录

    • [一、YAML 配置的读取流程(核心:配置绑定)](#一、YAML 配置的读取流程(核心:配置绑定))
      • [1. 配置文件加载:SpringBoot 自动识别 YAML](#1. 配置文件加载:SpringBoot 自动识别 YAML)
      • [2. 配置绑定:将 YAML 键值对映射到 Java 类](#2. 配置绑定:将 YAML 键值对映射到 Java 类)
        • [(1)@Value 注解(单个配置项绑定)](#(1)@Value 注解(单个配置项绑定))
        • [(2)@ConfigurationProperties 注解(批量绑定,核心)](#(2)@ConfigurationProperties 注解(批量绑定,核心))
      • [3. 容器管理:绑定后的配置类成为 Spring Bean](#3. 容器管理:绑定后的配置类成为 Spring Bean)
    • [二、数据库自动初始化原理(核心:自动配置 + 配置绑定)](#二、数据库自动初始化原理(核心:自动配置 + 配置绑定))
      • [前提:引入对应的 Starter 依赖](#前提:引入对应的 Starter 依赖)
      • [1. 自动配置类:DataSourceAutoConfiguration(初始化 DataSource)](#1. 自动配置类:DataSourceAutoConfiguration(初始化 DataSource))
      • [2. 自动配置类:MybatisAutoConfiguration(初始化 SqlSessionFactory)](#2. 自动配置类:MybatisAutoConfiguration(初始化 SqlSessionFactory))
        • (1)条件触发
        • [(2)依赖 DataSource 和 MyBatis 配置](#(2)依赖 DataSource 和 MyBatis 配置)
      • 最终效果
    • 三、核心逻辑总结(一张图看懂)

以整合Mybatis为例:

SpringBoot 能通过 YAML 配置自动读取数据库信息并初始化 DataSource、SqlSessionFactory,核心依赖 "配置绑定""自动配置" 两大机制,以下从 "YAML 读取流程" 和 "数据库自动初始化原理" 两部分拆解,结合源码逻辑和示例说明:

一、YAML 配置的读取流程(核心:配置绑定)

SpringBoot 读取 YAML 配置的核心是 "将配置文件中的键值对绑定到 Java 实体类",再由 Spring 容器管理这些实体类,供后续组件使用。整个流程分 3 步:

1. 配置文件加载:SpringBoot 自动识别 YAML

  • SpringBoot 启动时,会默认扫描 src/main/resources 目录下的application.yml (或 application.properties),这是 "约定大于配置" 的体现(无需手动指定配置文件路径)。
  • 加载逻辑:由ConfigFileApplicationListener 负责,它会监听 Spring 启动事件,自动加载默认配置文件,将配置内容解析为PropertySource(配置源),存入 Spring 的Environment(环境上下文)中。

2. 配置绑定:将 YAML 键值对映射到 Java 类

SpringBoot 提供两种核心绑定方式,数据库配置主要用第二种:

(1)@Value 注解(单个配置项绑定)

适合少量配置项,直接通过 ${key} 注入到 Bean 中:

java 复制代码
@Service
public class UserService {
    // 绑定 YAML 中的 spring.datasource.url
    @Value("${spring.datasource.url}")
    private String dbUrl;
}
(2)@ConfigurationProperties 注解(批量绑定,核心)

适合多配置项(如数据库连接信息、Redis 配置等),通过 prefix 指定 YAML 中的层级前缀,自动将该前缀下的所有配置项绑定到实体类的字段上:

java 复制代码
// 绑定 YAML 中 "spring.datasource" 前缀的所有配置
@ConfigurationProperties(prefix = "spring.datasource")
@Data // Lombok 简化 getter/setter(必须有 getter/setter 才能绑定)
public class DataSourceProperties {
    private String url;       // 对应 spring.datasource.url
    private String username;  // 对应 spring.datasource.username
    private String password;  // 对应 spring.datasource.password
    private String driverClassName; // 对应 spring.datasource.driver-class-name
}

3. 容器管理:绑定后的配置类成为 Spring Bean

  • 要让@ConfigurationProperties生效,需通过@EnableConfigurationProperties <font style="color:rgb(0, 0, 0);">@</font>启用,或直接在配置类上加@Component 注解,使其被 Spring 组件扫描识别:
java 复制代码
@Configuration
// 启用 DataSourceProperties 配置绑定,并将其注册为 Spring Bean
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceConfig {
}

二、数据库自动初始化原理(核心:自动配置 + 配置绑定)

你在 YAML 中填写数据库信息后,SpringBoot 能自动初始化 <font style="color:rgba(0, 0, 0, 0.85) !important;">DataSource</font><font style="color:rgba(0, 0, 0, 0.85) !important;">SqlSessionFactory</font>,本质是 "自动配置类 + 配置绑定后的属性" 协同工作,流程如下:

前提:引入对应的 Starter 依赖

要触发数据库自动配置,需先引入 Starter 依赖(以 MyBatis 为例):

xml 复制代码
<!-- SpringBoot JDBC  Starter:提供数据源自动配置 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- MyBatis  Starter:提供 SqlSessionFactory 自动配置 -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.0</version>
</dependency>
  • Starter 依赖会自动引入所需的核心组件(如 <font style="color:rgb(0, 0, 0);">HikariDataSource</font><font style="color:rgb(0, 0, 0);">MyBatis</font> 核心包),并触发对应的自动配置类。

1. 自动配置类:DataSourceAutoConfiguration(初始化 DataSource)

SpringBoot 内置DataSourceAutoConfiguration 类(属于spring-boot-starter-jdbc ),其核心逻辑是:

(1)条件触发
  • 当classpath 中存在DataSource 类(由 Starter 引入),且容器中没有手动定义的DataSource Bean 时,该自动配置类生效(@Conditional注解控制)。
(2)依赖配置绑定后的属性

DataSourceAutoConfiguration`` 会自动注入我们通过 YAML 绑定的DataSourceProperties :

java 复制代码
// SpringBoot 内置的自动配置类(简化源码)
@Configuration
@ConditionalOnClass(DataSource.class) // 存在 DataSource 类时生效
@EnableConfigurationProperties(DataSourceProperties.class) // 启用数据源配置绑定
public class DataSourceAutoConfiguration {

    // 注入绑定了 YAML 配置的 DataSourceProperties
    @Autowired
    private DataSourceProperties dataSourceProperties;

    // 自动创建 DataSource Bean,注入 Spring 容器
    @Bean
    @ConditionalOnMissingBean // 容器中没有 DataSource 时才创建
    public DataSource dataSource() {
        // 用 DataSourceProperties 中的属性(YAML 配置的数据库信息)初始化 DataSource
        return DataSourceBuilder.create()
        .url(dataSourceProperties.getUrl())
        .username(dataSourceProperties.getUsername())
        .password(dataSourceProperties.getPassword())
        .driverClassName(dataSourceProperties.getDriverClassName())
        .build();
    }
}
  • 最终创建的DataSource 是 SpringBoot 默认的HikariDataSource (高性能连接池),也可通过 YAML 配置切换为 Druid 等其他连接池。

2. 自动配置类:MybatisAutoConfiguration(初始化 SqlSessionFactory)

Mybatis-spring-boot-starter 引入了MybatisAutoConfiguration 类,核心逻辑:

(1)条件触发
  • 当classpath 中存在SqlSessionFactory 类(MyBatis 核心类),且容器中已存在DataSource Bean(由DataSourceAutoConfiguration 创建)时,生效。
(2)依赖 DataSource 和 MyBatis 配置
  • 自动注入DataSource (上一步创建的 Bean),并读取 YAML 中mybatis 前缀的配置(如mapper-locations):
java 复制代码
/**
 * MyBatis 自动配置类:根据 YAML 配置和 DataSource 自动创建 SqlSessionFactory
 */
@Configuration  // 标识为配置类
// 当类路径中存在 SqlSessionFactory 和 DataSource 时才生效(确保依赖已引入)
@ConditionalOnClass({SqlSessionFactory.class, DataSource.class})
// 启用 MyBatisProperties 配置绑定(关联 YAML 中 mybatis 前缀的配置)
@EnableConfigurationProperties(MyBatisProperties.class)
public class MybatisAutoConfiguration {

    // 注入 Spring 容器中的 DataSource(由 DataSourceAutoConfiguration 自动创建)
    private final DataSource dataSource;

    // 注入绑定了 YAML 配置的 MyBatisProperties(包含 mybatis.mapper-locations 等配置)
    private final MyBatisProperties mybatisProperties;

    // 构造函数自动注入依赖(Spring 自动匹配容器中的 Bean)
    public MybatisAutoConfiguration(DataSource dataSource, MyBatisProperties mybatisProperties) {
        this.dataSource = dataSource;
        this.mybatisProperties = mybatisProperties;
    }

    /**
     * 自动创建 SqlSessionFactory Bean,注入 Spring 容器
     * @ConditionalOnMissingBean:如果用户手动定义了 SqlSessionFactory,则此方法不生效(优先使用用户配置)
     */
    @Bean
    @ConditionalOnMissingBean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        // 1. 创建 MyBatis 提供的 SqlSessionFactoryBean(用于构建 SqlSessionFactory)
        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();

        // 2. 设置数据源(使用自动配置的 DataSource,关联 YAML 中的数据库连接信息)
        sessionFactoryBean.setDataSource(dataSource);

        // 3. 配置 Mapper 映射文件路径(从 MyBatisProperties 中读取 YAML 配置的 mybatis.mapper-locations)
        // 例如 YAML 中配置 mybatis.mapper-locations: classpath:mapper/*.xml
        sessionFactoryBean.setMapperLocations(
            new PathMatchingResourcePatternResolver()
                .getResources(mybatisProperties.getMapperLocations())  // 解析配置的路径
        );

        // 4. 其他配置(可选):如 MyBatis 全局配置文件、类型别名等(均来自 YAML 配置)
        if (mybatisProperties.getConfigLocation() != null) {
            // 配置 mybatis.config-location: classpath:mybatis-config.xml(自定义 MyBatis 全局配置)
            sessionFactoryBean.setConfigLocation(
                new PathMatchingResourcePatternResolver().getResource(mybatisProperties.getConfigLocation())
            );
        }
        // 设置类型别名包(mybatis.type-aliases-package: com.example.entity)
        sessionFactoryBean.setTypeAliasesPackage(mybatisProperties.getTypeAliasesPackage());

        // 5. 构建并返回 SqlSessionFactory 实例
        return sessionFactoryBean.getObject();
    }

}

最终效果

无需手动编写 DataSourceSqlSessionFactory 的配置代码,SpringBoot 通过"自动配置类"+"YAML 配置绑定",自动完成初始化并注册为 Spring Bean。

后续使用时,直接注入 Mapper 接口或 JdbcTemplate 即可:

java 复制代码
@RestController
public class UserController {
    @Autowired
    private UserMapper userMapper; // 直接注入,无需手动配置

    @GetMapping("/user/{id}")
    public User getUser(@PathVariable Long id) {
        return userMapper.selectById(id);
    }
}

三、核心逻辑总结(一张图看懂)

如果我的内容对你有帮助,请辛苦动动您的手指为我点赞,评论,收藏。感谢大家!!

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=h70g0sv71wz

相关推荐
Victor3562 小时前
Redis(130)Redis的压缩列表(Ziplist)是如何实现的?
后端
q***82912 小时前
Spring Boot 热部署
java·spring boot·后端
Victor3562 小时前
Redis(131)Redis的整数集合(Intset)是如何实现的?
后端
yuuki2332333 小时前
【数据结构】栈
c语言·数据结构·后端
flypwn4 小时前
TFCCTF 2025 WebLess题解
服务器·前端·数据库
n***i954 小时前
云原生数据库使用体验,与传统数据库差异
数据库·云原生
程序猿小蒜6 小时前
基于springboot的共享汽车管理系统开发与设计
java·开发语言·spring boot·后端·spring·汽车
悟空码字8 小时前
部署Spring Boot项目到Linux服务器数据盘
linux·spring boot·部署·数据盘
q***46528 小时前
在2023idea中如何创建SpringBoot
java·spring boot·后端