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; lookup = threadLocal;
} }
public static String processDataSourceKey(String dataSourceKey, Object mapper, Method method, Object[] arguments) { public static String processDataSourceKey(String dataSourceKey, Object targetOrProxy, Method method, Object[] arguments) {
String dsKey = DataSourceManager.processDataSourceKey(dataSourceKey, mapper, method, arguments); String dsKey = DataSourceManager.processDataSourceKey(dataSourceKey, targetOrProxy, method, arguments);
return dsKey != null ? dsKey : dataSourceKey; return dsKey != null ? dsKey : dataSourceKey;
} }

View File

@ -109,9 +109,9 @@ public class DataSourceManager {
return null; 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 实例,则不做处理,返回原始值 // 如果没有配置 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解析扩展 * 数据源key解析扩展
* *
* @param dataSourceKey 注解UseDataSource的value ,调用process时不会为null,不会为空{@link FlexMapperProxy#invoke(Object, Method, Object[])} * @param dataSourceKey 注解UseDataSource的value ,调用process时不会为null,可能为空字符{@link FlexMapperProxy#invoke(Object, Method, Object[])}And{@link com.mybatisflex.spring.datasource.DataSourceInterceptor#getDataSourceKey(Object, Method, Object[])}
* @param mapper Mapper对象(代理对象) * @param targetOrProxy AOP对象this或Mapper代理对象(当注解@UseDataSource使用到Mapper上时为proxy)
* @param method Mapper当前执行的方法函数 * @param method Mapper当前执行的方法函数
* @param arguments Mapper当前执行的函数参数 * @param arguments Mapper当前执行的函数参数
* @return 数据源名称可能为null null 时表示不符合当前处理器的处理 * @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,13 +59,13 @@ public class FlexMapperProxy<T> extends MybatisMapperProxy<T> {
try { try {
if (StringUtil.noText(finalDsKey)) { if (StringUtil.noText(finalDsKey)) {
// Mapper 方法上获取 UseDataSource的value值
finalDsKey = getMethodDsKey(method, proxy); finalDsKey = getMethodDsKey(method, proxy);
}
// 对数据源取值进行动态取值处理 // 对数据源取值进行动态取值处理
if (!StrUtil.isBlank(finalDsKey)) { if (!StrUtil.isBlank(finalDsKey)) {
finalDsKey = DataSourceKey.processDataSourceKey(finalDsKey, proxy, method, args); finalDsKey = DataSourceKey.processDataSourceKey(finalDsKey, proxy, method, args);
} }
}
// 通过自定义分配策略去获取最终的数据源 // 通过自定义分配策略去获取最终的数据源
finalDsKey = DataSourceKey.getShardingDsKey(finalDsKey, proxy, method, args); finalDsKey = DataSourceKey.getShardingDsKey(finalDsKey, proxy, method, args);

View File

@ -19,6 +19,7 @@ package com.mybatisflex.spring.datasource;
import com.mybatisflex.annotation.UseDataSource; import com.mybatisflex.annotation.UseDataSource;
import com.mybatisflex.core.datasource.DataSourceKey; import com.mybatisflex.core.datasource.DataSourceKey;
import com.mybatisflex.core.util.StringUtil; import com.mybatisflex.core.util.StringUtil;
import com.mybatisflex.processor.util.StrUtil;
import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
import org.springframework.core.MethodClassKey; import org.springframework.core.MethodClassKey;
@ -44,7 +45,7 @@ public class DataSourceInterceptor implements MethodInterceptor {
@Override @Override
public Object invoke(MethodInvocation invocation) throws Throwable { 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)) { if (StringUtil.noText(dsKey)) {
return invocation.proceed(); return invocation.proceed();
} }
@ -56,11 +57,15 @@ public class DataSourceInterceptor implements MethodInterceptor {
} }
} }
private String getDataSourceKey(Method method, Class<?> targetClass) { private String getDataSourceKey(Object target, Method method, Object[] arguments) {
Object cacheKey = new MethodClassKey(method, targetClass); Object cacheKey = new MethodClassKey(method, target.getClass());
String dsKey = this.dsCache.get(cacheKey); String dsKey = this.dsCache.get(cacheKey);
if (dsKey == null) { 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); this.dsCache.put(cacheKey, dsKey);
} }
return dsKey; return dsKey;