Spring Boot 动态数据源
利用AOP来实现多数据源的动态切换功能。
1.前言
AbstractRoutingDataSource是Spring2.0.1版本引入的一个抽象类,它提供了多数据源的支持能力。AbstractRoutingDataSource抽象类定义了抽象的determineCurrentLookupKey方法,子类只需实现此方法,进而动态确定要使用的数据源。
AbstractRoutingDataSource
public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {
@Nullable
private Map<Object, Object> targetDataSources;
@Nullable
private Object defaultTargetDataSource;
private boolean lenientFallback = true;
private DataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
@Nullable
private Map<Object, DataSource> resolvedDataSources;
@Nullable
private DataSource resolvedDefaultDataSource;
......
protected DataSource determineTargetDataSource() {
Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
Object lookupKey = this.determineCurrentLookupKey();
DataSource dataSource = (DataSource)this.resolvedDataSources.get(lookupKey);
if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
dataSource = this.resolvedDefaultDataSource;
}
if (dataSource == null) {
throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
} else {
return dataSource;
}
}
@Nullable
protected abstract Object determineCurrentLookupKey();
}
- 调用determineCurrentLookupKey方法来获取数据源名称key
- 从resolvedDataSources属性中得到对应的DataSource对象。
- 如果找不到DataSource对象或者数据源名称key不存在则使用resolvedDefaultDataSource。
2.实现思路
- 提前准备好多个数据源
- 将其存入一个Map中 (Map的Key是对应数据源的名称,而Value则是对应的数据源)
- 将Map设置到AbstractRoutingDataSource对象的resolvedDataSources属性中
- 当执行数据库操作的时候就通过一个Key来从Map中获取对应的数据源实例
- 执行对应的数据库操作
3.项目实战
3.1 项目初始化
新建一个spring的项目:multi-source
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.flowboot</groupId>
<artifactId>multi-source</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>multi-source</name>
<description>multi