Skip to content

Commit 6f7712e

Browse files
committed
feat: 添加数据源配置类,解析并配置动态数据源
1 parent 463f251 commit 6f7712e

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package top.cadecode.common.config;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import lombok.extern.slf4j.Slf4j;
5+
import org.mybatis.spring.annotation.MapperScan;
6+
import org.springframework.beans.factory.config.YamlMapFactoryBean;
7+
import org.springframework.boot.context.properties.bind.Binder;
8+
import org.springframework.context.annotation.Bean;
9+
import org.springframework.context.annotation.Configuration;
10+
import org.springframework.core.env.Environment;
11+
import org.springframework.core.io.ClassPathResource;
12+
import top.cadecode.common.datasource.DynamicDataSource;
13+
import top.cadecode.common.datasource.DynamicDataSource.DynamicDataSourceHolder;
14+
15+
import javax.sql.DataSource;
16+
import java.util.*;
17+
18+
/**
19+
* @author Li Jun
20+
* @date 2021/12/3
21+
* @description 数据源配置类
22+
*/
23+
@Slf4j
24+
@Configuration
25+
@MapperScan({"top.cadecode.model"})
26+
@RequiredArgsConstructor
27+
public class DataSourceConfig {
28+
29+
private final Environment environment;
30+
31+
@Bean
32+
public DynamicDataSource dynamicDataSource() {
33+
log.info("配置动态数据源");
34+
DynamicDataSource dynamicDataSource = new DynamicDataSource();
35+
// 读取 dataSource.yml
36+
YamlMapFactoryBean dateSourceMapFactory = new YamlMapFactoryBean();
37+
dateSourceMapFactory.setResources(new ClassPathResource("dataSource.yml"));
38+
Map<String, Object> dataSourceMap = dateSourceMapFactory.getObject();
39+
// 获取所有数据源 key
40+
Set<String> keys = dataSourceMap.keySet();
41+
// 存储 keys 到 DynamicDataSourceHolder
42+
DynamicDataSourceHolder.addDataSourceKeys(keys);
43+
// 定义数据源容器,用于设置到 dynamicDataSource
44+
Map<Object, Object> targetDataSourceMap = new HashMap<>();
45+
// 遍历 keys
46+
keys.forEach(key -> {
47+
log.info("解析数据源配置 " + key);
48+
Map<String, Object> configMap = this.checkDataSourceMap(dataSourceMap, key);
49+
// 取出数据源类型和 isDefault
50+
String type = (String) configMap.get("type");
51+
Boolean isDefault = (Boolean) configMap.get("isDefault");
52+
// 生成数据源实例
53+
DataSource dataSource = (DataSource) Binder.get(environment)
54+
.bind(key + ".config", this.checkDataSourceType(type, key)).get();
55+
targetDataSourceMap.put(key, dataSource);
56+
// 判断是否是默认数据源
57+
if (isDefault != null && isDefault.equals(true) && !dynamicDataSource.hasDefaultDataSource()) {
58+
dynamicDataSource.setDefaultTargetDataSource(dataSource);
59+
log.info("设置默认数据源为 " + key);
60+
}
61+
});
62+
// 判断是否设置默认数据源
63+
if (!dynamicDataSource.hasDefaultDataSource()) {
64+
throw new IllegalArgumentException("未指定默认数据源,使用 isDefault: true 指定");
65+
}
66+
// 设置数据源到 dynamicDataSource
67+
dynamicDataSource.setTargetDataSources(targetDataSourceMap);
68+
return dynamicDataSource;
69+
}
70+
71+
/**
72+
* 校验 dataSourceMap
73+
*/
74+
private Map<String, Object> checkDataSourceMap(Map<String, Object> dataSourceMap, String key) {
75+
if (dataSourceMap.get(key) == null || !(dataSourceMap.get(key) instanceof Map)) {
76+
throw new IllegalArgumentException("数据源 " + key + " 配置有误,无法解析");
77+
}
78+
return (Map<String, Object>) dataSourceMap.get(key);
79+
}
80+
81+
/**
82+
* 获取数据源 class
83+
*/
84+
private Class<?> checkDataSourceType(String type, String key) {
85+
Class<?> dataSourceClass;
86+
try {
87+
dataSourceClass = Class.forName(type);
88+
// 判断是否是 DataSource 类型
89+
if (!DataSource.class.isAssignableFrom(dataSourceClass)) {
90+
throw new IllegalArgumentException("数据源 " + key + " 的类型 " + type + " 不合适");
91+
}
92+
} catch (ClassNotFoundException e) {
93+
throw new IllegalArgumentException("数据源 " + key + " 的类型 " + type + " 不存在");
94+
}
95+
return dataSourceClass;
96+
}
97+
}

0 commit comments

Comments
 (0)