1、对动态数据源@UseDataSource的value值进行动态解析区分Spring模式下和非Spring模式下

This commit is contained in:
chxlay 2024-12-09 14:56:01 +08:00
parent 0bcdef685e
commit 475b0ecb3a
5 changed files with 21 additions and 16 deletions

View File

@ -78,8 +78,8 @@ public class DataSourceKey {
lookup = threadLocal;
}
public static String processDataSourceKey(String dataSourceKey, Object mapper, Method method, Object[] arguments) {
String dsKey = DataSourceManager.processDataSourceKey(dataSourceKey, mapper, method, arguments);
public static String processDataSourceKey(String dataSourceKey, Object targetOrProxy, Method method, Object[] arguments) {
String dsKey = DataSourceManager.processDataSourceKey(dataSourceKey, targetOrProxy, method, arguments);
return dsKey != null ? dsKey : dataSourceKey;
}

View File

@ -109,9 +109,9 @@ public class DataSourceManager {
return null;
}
static String processDataSourceKey(String dataSourceKey, Object mapper, Method method, Object[] arguments) {
static String processDataSourceKey(String dataSourceKey, Object targetOrProxy, Method method, Object[] arguments) {
// 如果没有配置 DataSourceProcessor 实例,则不做处理,返回原始值
return dataSourceProcessor == null ? dataSourceKey : dataSourceProcessor.process(dataSourceKey, mapper, method, arguments);
return dataSourceProcessor == null ? dataSourceKey : dataSourceProcessor.process(dataSourceKey, targetOrProxy, method, arguments);
}

View File

@ -16,12 +16,12 @@ public interface DataSourceProcessor {
/**
* 数据源key解析扩展
*
* @param dataSourceKey 注解UseDataSource的value ,调用process时不会为null,不会为空{@link FlexMapperProxy#invoke(Object, Method, Object[])}
* @param mapper Mapper对象(代理对象)
* @param dataSourceKey 注解UseDataSource的value ,调用process时不会为null,可能为空字符{@link FlexMapperProxy#invoke(Object, Method, Object[])}And{@link com.mybatisflex.spring.datasource.DataSourceInterceptor#getDataSourceKey(Object, Method, Object[])}
* @param targetOrProxy AOP对象this或Mapper代理对象(当注解@UseDataSource使用到Mapper上时为proxy)
* @param method Mapper当前执行的方法函数
* @param arguments Mapper当前执行的函数参数
* @return 数据源名称可能为null null 时表示不符合当前处理器的处理
*/
String process(String dataSourceKey, Object mapper, Method method, Object[] arguments);
String process(String dataSourceKey, Object targetOrProxy, Method method, Object[] arguments);
}

View File

@ -59,12 +59,12 @@ public class FlexMapperProxy<T> extends MybatisMapperProxy<T> {
try {
if (StringUtil.noText(finalDsKey)) {
// Mapper 方法上获取 UseDataSource的value值
finalDsKey = getMethodDsKey(method, proxy);
}
// 对数据源取值进行动态取值处理
if (!StrUtil.isBlank(finalDsKey)) {
finalDsKey = DataSourceKey.processDataSourceKey(finalDsKey, proxy, method, args);
// 对数据源取值进行动态取值处理
if (!StrUtil.isBlank(finalDsKey)) {
finalDsKey = DataSourceKey.processDataSourceKey(finalDsKey, proxy, method, args);
}
}
// 通过自定义分配策略去获取最终的数据源

View File

@ -19,6 +19,7 @@ package com.mybatisflex.spring.datasource;
import com.mybatisflex.annotation.UseDataSource;
import com.mybatisflex.core.datasource.DataSourceKey;
import com.mybatisflex.core.util.StringUtil;
import com.mybatisflex.processor.util.StrUtil;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.core.MethodClassKey;
@ -44,7 +45,7 @@ public class DataSourceInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String dsKey = getDataSourceKey(invocation.getMethod(), invocation.getThis().getClass());
String dsKey = getDataSourceKey(invocation.getThis(), invocation.getMethod(), invocation.getArguments());
if (StringUtil.noText(dsKey)) {
return invocation.proceed();
}
@ -56,11 +57,15 @@ public class DataSourceInterceptor implements MethodInterceptor {
}
}
private String getDataSourceKey(Method method, Class<?> targetClass) {
Object cacheKey = new MethodClassKey(method, targetClass);
private String getDataSourceKey(Object target, Method method, Object[] arguments) {
Object cacheKey = new MethodClassKey(method, target.getClass());
String dsKey = this.dsCache.get(cacheKey);
if (dsKey == null) {
dsKey = determineDataSourceKey(method, targetClass);
dsKey = determineDataSourceKey(method, target.getClass());
// 对数据源取值进行动态取值处理
if (!StrUtil.isBlank(dsKey)) {
dsKey = DataSourceKey.processDataSourceKey(dsKey, target, method, arguments);
}
this.dsCache.put(cacheKey, dsKey);
}
return dsKey;