为什么在多数据源的情况下,单数据源的自动配置类会失效?

embedded/2024/12/29 1:45:44/

在 Spring Boot 中,DataSourceAutoConfiguration 是单数据源情况下的默认自动配置类。当引入多数据源方案(例如 dynamic-datasource-spring-boot-starter)后,单数据源的自动配置机制会失效,原因主要在于多数据源自动配置类的优先加载和 Spring Boot 的条件装配逻辑。


1. 单数据源的自动配置机制

Spring Boot 的 DataSourceAutoConfiguration 是为单数据源提供的默认配置,依赖以下核心注解:

  • @ConditionalOnMissingBean
    自动配置的核心条件之一,只有在容器中不存在 DataSourceXADataSource 实例(对象)的情况下,Spring 才会装配默认的数据源。

关键代码如下:

java">@Configuration(proxyBeanMethods = false
)
@Conditional({PooledDataSourceCondition.class})
@ConditionalOnMissingBean({DataSource.class, XADataSource.class})
@Import({DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class, DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class, DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class})
protected static class PooledDataSourceConfiguration {protected PooledDataSourceConfiguration() {}@Bean@ConditionalOnMissingBean({JdbcConnectionDetails.class})PropertiesJdbcConnectionDetails jdbcConnectionDetails(DataSourceProperties properties) {return new PropertiesJdbcConnectionDetails(properties);}
}

核心逻辑
如果容器中已经存在 DataSourceXADataSource实例(对象)的情况下,上述配置将不会生效。这是为了避免重复配置或冲突。


2. 多数据源的自动配置机制

当引入 dynamic-datasource-spring-boot-starter 后,自动配置类 DynamicDataSourceAutoConfiguration会使得 DataSourceAutoConfiguration自动配置类中加载数据源失效。

DynamicDataSourceAutoConfiguration类的定义如下:

java">@AutoConfigureBefore(value = DataSourceAutoConfiguration.class,name = "com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure"
)
public class DynamicDataSourceAutoConfiguration implements InitializingBean {// 动态数据源的配置逻辑
}
  • @AutoConfigureBefore
    确保 DynamicDataSourceAutoConfigurationDataSourceAutoConfiguration 之前加载。且 DynamicDataSourceAutoConfiguration 在容器初始化时,会预先创建和注册动态数据源的 DataSource 实例,这使得 @ConditionalOnMissingBean 的条件不再满足。所以DataSourceAutoConfiguration 中的自动注入数据源就无法生效。

3. 为什么单数据源的自动配置类失效?

单数据源的自动配置类失效的原因可以归结为以下几点:

3.1 动态数据源的优先加载

@AutoConfigureBefore 明确指示 DynamicDataSourceAutoConfiguration 在默认的 DataSourceAutoConfiguration 之前加载。因此,动态数据源配置优先于单数据源配置完成初始化。

3.2 提前注入 DataSource Bean

在动态数据源方案中,DynamicDataSourceAutoConfiguration 会在 DataSourceAutoConfiguration 执行前,向容器注册一个动态的 DataSource Bean(通常是 DynamicRoutingDataSource)。这使得 @ConditionalOnMissingBean(DataSource.class) 的条件不再满足,导致单数据源的自动配置逻辑被跳过。

3.3 替代单数据源配置

动态数据源的目标是支持多个数据源,同时提供路由、切换等功能。而单数据源的默认配置显然无法满足这些需求,因此被动态数据源框架的配置完全替代。


4. 总结

在引入 dynamic-datasource-spring-boot-starter 后,单数据源的自动配置类失效的根本原因是多数据源自动配置类的优先加载和条件装配的逻辑冲突。具体表现如下:

  1. 优先加载:多数据源通过 @AutoConfigureBefore 指定在单数据源自动配置之前加载。
  2. 条件不满足:多数据源自动配置类提前注册了 DataSource,使得 DataSourceAutoConfiguration@ConditionalOnMissingBean 条件不成立。
  3. 逻辑替代:多数据源需要更复杂的配置逻辑,单数据源配置被替代。

这种机制是 Spring Boot 条件装配机制和自动配置优先级协同工作的结果,也是动态数据源实现灵活性的重要基础。


http://www.ppmy.cn/embedded/148807.html

相关文章

补充--C++的项目结构和管理

1. C项目结构 一个典型的C项目结构通常包括以下几个部分: 1.1 项目根目录 项目的根目录是所有文件和子目录的起点,通常包含以下内容: 源代码目录(src/):存放所有源代码文件(.cpp和.h&#x…

Vite创建Vue3工程并引入ElementPlus(图文详情)

Vite创建Vue3工程并引入ElementPlus(图文详细) 1 Vite创建Vue3工程 请确保本机已经正常安装了node18以上版本,例如本项目使用18.19.0版本 安装多版本node请参考:使用NVM安装管理node版本 使用vite创建vue3工,参考vi…

【C++ 基础】从C到C++有哪些变化

C到C C相比C语言来说,多了两个核心,五个内容:1、面向对象的思维;2、模板(泛型编型)1.bool 2.引用 3.内联 4.重载 5.缺省参数变量 数据类型 bool 布尔 占1个字节 取值:true false bool isMax(i…

下载运行Vue开源项目vue-pure-admin

git地址:GitHub - pure-admin/vue-pure-admin: 全面ESMVue3ViteElement-PlusTypeScript编写的一款后台管理系统(兼容移动端) 安装pnpm npm install -g pnpm # 国内 淘宝 镜像源 pnpm config set registry https://registry.npmmirror.com/…

CESS 出席华盛顿区块链政策峰会:参与国家安全与数据隐私保护专题讨论

12 月 16 日-17 日,由美国区块链协会(Blockchain Association,简称 BA)主办的 2024 区块链政策峰会在华盛顿特区盛大召开。 本次峰会吸引了众多区块链行业领导者、政策制定者和监管机构参与,围绕区块链政策、监管框架及…

记录C++学习 16

运算符及其重载 运算符 运算符实际就是函数 C中的运算符有 - * / % ^ & | ~ ! < > - * / % ^ & | << >> >> << ! < > <> && || -- , ->* -> ( ) [ ] 运算符的重载 重载本质上是给运算符重新赋予…

预览和下载 (pc和微信小程序)

1.微信小程序 预览pdf 或者 图片等 //utils.js 文件//通过接口返回文件链接 打开文档 export default function previewFile({ downLinkUrl, tempFilePath }) {let url "https://" downLinkUrl.replace("http://", "").replace("https:…

关于小程序内嵌h5打开新的小程序

关于小程序内嵌h5打开新的小程序 三种方式 https://juejin.cn/post/7055551463489011749 只依赖于h5本身的就是 https://huaweicloud.csdn.net/64f97ebb6b896f66024ca16c.html https://juejin.cn/post/7055551463489011749 navigateToMiniProgram 故小程序webview里的h5无法…