记一次dynamic的动态数据源加载问题

项目在集成新的开源模块后,出现多数据源配置失效的问题,只加载了一个数据源。经过追踪发现,是由于dynamicbean的单例性质,以及开源模块提前注入了dataSourcebean,从而破坏了多数据源设置。解决方法是取消提前注入bean的操作,或者参考相关博主提供的第二种解决方案。

背景

今天项目集成了一个开源的模块,没想到多数据源就此崩溃.

表现形式为:

本项目一共3个数据源,之前每次启动时,能看到3个数据源加载成功的日志, 而现在每次启动都只有一个{dataSource-1}的数据源被加载, 也就是说, 我剩下的两个数据源丢了

解决问题

跟踪了一下午的bean加载终于找到了罪魁祸首 , 原因是dynamic的bean为单例限制, 而我集成的那个开源模块提前注入了dataSource这个bean ,所以导致数据源变成非多数据源了

解决办法的灵感来自于一位很强的博主 https://blog.youkuaiyun.com/mmmmmmmmo/article/details/128563559

我因为是新引入的这个模块,所以我直接把提前注入bean的地方取消了, 如果你的项目不适合这种方法, 记得去上面博主那里看看第二种方法, 博主讲的很详细,我就不贴那么多图了

### 无数据源配置时 dynamic-datasource 的正确启动解决方案 `dynamic-datasource` 提供了一种机制来支持 **无数据源启动**,这使得应用程序可以在未预先配置任何数据源的情况下正常运行[^2]。以下是具体的实现方式: #### 1. 使用 `NoDataSource` 或者空数据源占位 可以通过设置一个虚拟的或空的数据源作为默认值,从而满足框架对初始状态的要求。这种方式不会影响后续动态添加数据源的功能。 ```java @Configuration public class DataSourceConfig { @Bean public DynamicRoutingDataSource dataSource() { DynamicRoutingDataSource dynamicDataSource = new DynamicRoutingDataSource(); // 设置默认为空数据源 dynamicDataSource.setPrimaryDataSource(new NoDataSource()); dynamicDataSource.setDataSources(Collections.emptyMap()); return dynamicDataSource; } } ``` 上述代码中使用了 `NoDataSource` 类型作为占位符,这是一种特殊的实现,表示当前不存在实际可用的数据源[^3]。 --- #### 2. 开启懒加载功能 为了减少资源消耗以及提高灵活性,`dynamic-datasource` 支持 **懒加载** 数据源的方式。这意味着只有当某个特定数据源被请求时才会真正去实例化它。此特性可通过如下方式进行启用: ```yaml spring: datasource: dynamic: lazy-initialize: true ``` 通过以上 YAML 配置项开启懒加载之后,在应用启动阶段即使没有任何显式定义好的物理数据源也不会报错。 --- #### 3. 动态注册数据源 即便是在程序刚开始执行期间尚未指定任何外部存储链接信息,仍然能够利用 API 接口手动向容器里注入新的数据源对象。例如下面展示了一个简单的例子说明如何完成这项任务: ```java @Autowired private DynamicDataSourceContextHolder contextHolder; @Autowired private DynamicRoutingDataSource dynamicRoutingDataSource; public void addNewDataSource(String name, DataSource ds){ Map<String, DataSource> targetDataSources = dynamicRoutingDataSource.getDataSources(); if (!targetDataSources.containsKey(name)){ synchronized (this){ if(!targetDataSources.containsKey(name)){ targetDataSources.put(name, ds); // 更新到动态路由数据源dynamicRoutingDataSource.addDataSource(name, ds); System.out.println("Added a new data source named:" +name); } } } } ``` 这种方法允许开发者灵活控制何时何处新增加额外的支持数据库连接池[^5]。 --- #### 注意事项 尽管实现了零预设条件下的初始化过程,但在某些特殊情况下仍需要注意一些潜在陷阱。比如涉及到事务管理的部分可能需要特别处理以避免冲突或者失效的情况发生[^4]。 --- ### 总结 综上所述,针对 `dynamic-datasource` 在完全没有提前设定好对应关系情形下的平稳激活需求,主要依靠以下几个方面达成目标:一是借助假象节点填补空白位置;二是延迟真实内容生成时机直到必要时刻才触发动作;三是提供了便捷途径让用户自行扩充体系内的成员构成][^[^23]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值