SpringBoot YAML 配置读取机制 + 数据库自动初始化原理
👨💻程序员三明治:个人主页
🔥 个人专栏: 《设计模式精解》《重学数据结构》
🤞先做到 再看见!
目录
以整合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 中:
@ServicepublicclassUserService{// 绑定 YAML 中的 spring.datasource.url@Value("${spring.datasource.url}")privateString dbUrl;}(2)@ConfigurationProperties 注解(批量绑定,核心)
适合多配置项(如数据库连接信息、Redis 配置等),通过 prefix 指定 YAML 中的层级前缀,自动将该前缀下的所有配置项绑定到实体类的字段上:
// 绑定 YAML 中 "spring.datasource" 前缀的所有配置@ConfigurationProperties(prefix ="spring.datasource")@Data// Lombok 简化 getter/setter(必须有 getter/setter 才能绑定)publicclassDataSourceProperties{privateString url;// 对应 spring.datasource.urlprivateString username;// 对应 spring.datasource.usernameprivateString password;// 对应 spring.datasource.passwordprivateString driverClassName;// 对应 spring.datasource.driver-class-name}3. 容器管理:绑定后的配置类成为 Spring Bean
- 要让@ConfigurationProperties生效,需通过@EnableConfigurationProperties
<font>@</font>启用,或直接在配置类上加@Component 注解,使其被 Spring 组件扫描识别:
@Configuration// 启用 DataSourceProperties 配置绑定,并将其注册为 Spring Bean@EnableConfigurationProperties(DataSourceProperties.class)publicclassDataSourceConfig{}二、数据库自动初始化原理(核心:自动配置 + 配置绑定)
你在 YAML 中填写数据库信息后,SpringBoot 能自动初始化 <font>DataSource</font>、<font>SqlSessionFactory</font>,本质是 “自动配置类 + 配置绑定后的属性” 协同工作,流程如下:
前提:引入对应的 Starter 依赖
要触发数据库自动配置,需先引入 Starter 依赖(以 MyBatis 为例):
<!-- 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>HikariDataSource</font>、<font>MyBatis</font>核心包),并触发对应的自动配置类。
1. 自动配置类:DataSourceAutoConfiguration(初始化 DataSource)
SpringBoot 内置DataSourceAutoConfiguration 类(属于spring-boot-starter-jdbc ),其核心逻辑是:
(1)条件触发
- 当classpath 中存在DataSource 类(由 Starter 引入),且容器中没有手动定义的DataSource Bean 时,该自动配置类生效(@Conditional注解控制)。
(2)依赖配置绑定后的属性
DataSourceAutoConfiguration`` 会自动注入我们通过 YAML 绑定的DataSourceProperties :
// SpringBoot 内置的自动配置类(简化源码)@Configuration@ConditionalOnClass(DataSource.class)// 存在 DataSource 类时生效@EnableConfigurationProperties(DataSourceProperties.class)// 启用数据源配置绑定publicclassDataSourceAutoConfiguration{// 注入绑定了 YAML 配置的 DataSourceProperties@AutowiredprivateDataSourceProperties dataSourceProperties;// 自动创建 DataSource Bean,注入 Spring 容器@Bean@ConditionalOnMissingBean// 容器中没有 DataSource 时才创建publicDataSourcedataSource(){// 用 DataSourceProperties 中的属性(YAML 配置的数据库信息)初始化 DataSourcereturnDataSourceBuilder.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):
/** * MyBatis 自动配置类:根据 YAML 配置和 DataSource 自动创建 SqlSessionFactory */@Configuration// 标识为配置类// 当类路径中存在 SqlSessionFactory 和 DataSource 时才生效(确保依赖已引入)@ConditionalOnClass({SqlSessionFactory.class,DataSource.class})// 启用 MyBatisProperties 配置绑定(关联 YAML 中 mybatis 前缀的配置)@EnableConfigurationProperties(MyBatisProperties.class)publicclassMybatisAutoConfiguration{// 注入 Spring 容器中的 DataSource(由 DataSourceAutoConfiguration 自动创建)privatefinalDataSource dataSource;// 注入绑定了 YAML 配置的 MyBatisProperties(包含 mybatis.mapper-locations 等配置)privatefinalMyBatisProperties mybatisProperties;// 构造函数自动注入依赖(Spring 自动匹配容器中的 Bean)publicMybatisAutoConfiguration(DataSource dataSource,MyBatisProperties mybatisProperties){this.dataSource = dataSource;this.mybatisProperties = mybatisProperties;}/** * 自动创建 SqlSessionFactory Bean,注入 Spring 容器 * @ConditionalOnMissingBean:如果用户手动定义了 SqlSessionFactory,则此方法不生效(优先使用用户配置) */@Bean@ConditionalOnMissingBeanpublicSqlSessionFactorysqlSessionFactory()throwsException{// 1. 创建 MyBatis 提供的 SqlSessionFactoryBean(用于构建 SqlSessionFactory)SqlSessionFactoryBean sessionFactoryBean =newSqlSessionFactoryBean();// 2. 设置数据源(使用自动配置的 DataSource,关联 YAML 中的数据库连接信息) sessionFactoryBean.setDataSource(dataSource);// 3. 配置 Mapper 映射文件路径(从 MyBatisProperties 中读取 YAML 配置的 mybatis.mapper-locations)// 例如 YAML 中配置 mybatis.mapper-locations: classpath:mapper/*.xml sessionFactoryBean.setMapperLocations(newPathMatchingResourcePatternResolver().getResources(mybatisProperties.getMapperLocations())// 解析配置的路径);// 4. 其他配置(可选):如 MyBatis 全局配置文件、类型别名等(均来自 YAML 配置)if(mybatisProperties.getConfigLocation()!=null){// 配置 mybatis.config-location: classpath:mybatis-config.xml(自定义 MyBatis 全局配置) sessionFactoryBean.setConfigLocation(newPathMatchingResourcePatternResolver().getResource(mybatisProperties.getConfigLocation()));}// 设置类型别名包(mybatis.type-aliases-package: com.example.entity) sessionFactoryBean.setTypeAliasesPackage(mybatisProperties.getTypeAliasesPackage());// 5. 构建并返回 SqlSessionFactory 实例return sessionFactoryBean.getObject();}}最终效果
无需手动编写 DataSource、SqlSessionFactory 的配置代码,SpringBoot 通过“自动配置类”+“YAML 配置绑定”,自动完成初始化并注册为 Spring Bean。
后续使用时,直接注入 Mapper 接口或 JdbcTemplate 即可:
@RestControllerpublicclassUserController{@AutowiredprivateUserMapper userMapper;// 直接注入,无需手动配置@GetMapping("/user/{id}")publicUsergetUser(@PathVariableLong id){return userMapper.selectById(id);}}三、核心逻辑总结(一张图看懂)

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

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