matrix.boot.jdbc.beans.DynamicDataSource Maven / Gradle / Ivy
The newest version!
package matrix.boot.jdbc.beans;
import com.alibaba.druid.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import matrix.boot.based.utils.AnnotationUtil;
import matrix.boot.based.utils.WebUtil;
import matrix.boot.common.utils.StringUtil;
import matrix.boot.jdbc.annotation.TargetDataSource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 动态数据源
*
* @author wangcheng
*/
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource {
/**
* 查找当前key
*
* @return key信息
*/
@Override
protected Object determineCurrentLookupKey() {
Object key = DynamicDataSourceHolder.getDataSourceKey();
log.debug("==> select datasource key [{}]", key);
return key;
}
/**
* 后置配置
*/
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
}
/**
* 动态数据源持有者
*/
@Slf4j
public static class DynamicDataSourceHolder {
private static final ThreadLocal holder = new ThreadLocal<>();
/**
* 获取数据源的key
*
* @return 数据源的key
*/
public static String getDataSourceKey() {
String key = holder.get();
if (StringUtils.isEmpty(key)) {
return WebUtil.getBean(MoreDataSource.class).getMasterDataSourceKey();
}
return key;
}
/**
* 设置当前数据源的key
*
* @param key 键
*/
public static void setDataSourceKey(String key) {
holder.set(key);
}
/**
* 清除当前数据源的key
*/
public static void clearDataSourceKey() {
holder.remove();
}
/**
* 切换数据源
* @param dbKey 数据库标识
*/
public static void switchDataSource(String dbKey) {
if (StringUtil.isEmpty(dbKey)) {
return;
}
String dbName;
if (dbKey.startsWith("$")) {
//存在变量,取出来转换
Environment environment = WebUtil.getBean(Environment.class);
dbName = environment.getProperty(dbKey.replace("${", "").replace("}", ""));
if (StringUtils.isEmpty(dbName)) {
dbName = WebUtil.getBean(MoreDataSource.class).getMasterDataSourceKey();
}
} else {
dbName = dbKey;
}
DynamicDataSourceHolder.setDataSourceKey(dbName);
}
/**
* 切换动态数据源
* @param joinPoint 切入点
*/
public static void switchDataSource(ProceedingJoinPoint joinPoint) {
TargetDataSource targetDataSource = AnnotationUtil.getAnnotation(joinPoint, TargetDataSource.class);
if (targetDataSource != null) {
switchDataSource(targetDataSource.value());
}
}
}
}