为了帮助理解此原理,在SpringBoot 2.1.17版本上,借助一个具体的功能来展开讨论(这个功能就是通过页面配置数据源基本信息,并进行测试连接)。
前端页面配置数据源名称(唯一标识)、类型(mysql/oracl 等)、ip、端口、数据库名称、用户名、密码。后台根据配置信息生成创建com.alibaba.druid.pool.DruidDataSource 的必要信息。
1.创建 DynamicDataSource 集成AbstractRoutingDataSource
/**
* 动态数据源
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
/**
* 当前已加载的数据源
*/
private Map<Object, Object> currentDataSources = new HashMap<>(8);
private DruidProperties druidProperties;
//=====================================分析1
public DynamicDataSource(DataSource defaultTargetDataSource,
Map<Object, Object> targetDataSources, DruidProperties druidProperties) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
setCurrentDataSources(targetDataSources);
super.afterPropertiesSet();
this.druidProperties = druidProperties;
}
private void setCurrentDataSources(Map<Object, Object> targetDataSources) {
this.currentDataSources = targetDataSources;
}
public Map<Object, Object> getCurrentDataSources() {
return this.currentDataSources;
}
/**
* 重置数据源
*/
private void resetDataSources(Map<Object, Object> targetDataSources) {
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContextHolder.getDataSourceType();
}
public void addDataSource(String username, String password,
String url, String driverClassName, String dsKey) {
if(! currentDataSources.containsKey(dsKey)){//不存在则put
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setUrl(url);
dataSource.setDriverClassName(driverClassName);