parent
8079e98e9a
commit
1f9f2cc92e
@ -1,24 +0,0 @@ |
|||||||
package com.zilber.boot.annotation; |
|
||||||
|
|
||||||
import com.zilber.boot.enums.DataSourceType; |
|
||||||
|
|
||||||
import java.lang.annotation.*; |
|
||||||
|
|
||||||
/** |
|
||||||
* 自定义多数据源切换注解 |
|
||||||
* |
|
||||||
* 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准 |
|
||||||
* |
|
||||||
* @author lsc |
|
||||||
*/ |
|
||||||
@Target({ ElementType.METHOD, ElementType.TYPE }) |
|
||||||
@Retention(RetentionPolicy.RUNTIME) |
|
||||||
@Documented |
|
||||||
@Inherited |
|
||||||
public @interface DataSource |
|
||||||
{ |
|
||||||
/** |
|
||||||
* 切换数据源名称 |
|
||||||
*/ |
|
||||||
public DataSourceType value() default DataSourceType.MASTER; |
|
||||||
} |
|
@ -1,73 +0,0 @@ |
|||||||
package com.zilber.boot.framework.aspectj; |
|
||||||
|
|
||||||
|
|
||||||
import com.zilber.boot.annotation.DataSource; |
|
||||||
import com.zilber.boot.framework.datasource.DynamicDataSourceContextHolder; |
|
||||||
import com.zilber.boot.utils.StringUtils; |
|
||||||
import org.aspectj.lang.ProceedingJoinPoint; |
|
||||||
import org.aspectj.lang.annotation.Around; |
|
||||||
import org.aspectj.lang.annotation.Aspect; |
|
||||||
import org.aspectj.lang.annotation.Pointcut; |
|
||||||
import org.aspectj.lang.reflect.MethodSignature; |
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
import org.springframework.core.annotation.AnnotationUtils; |
|
||||||
import org.springframework.core.annotation.Order; |
|
||||||
import org.springframework.stereotype.Component; |
|
||||||
import java.util.Objects; |
|
||||||
|
|
||||||
/** |
|
||||||
* 多数据源处理 |
|
||||||
* |
|
||||||
* @author lsc |
|
||||||
*/ |
|
||||||
@Aspect |
|
||||||
@Order(1) |
|
||||||
@Component |
|
||||||
public class DataSourceAspect |
|
||||||
{ |
|
||||||
protected Logger logger = LoggerFactory.getLogger(getClass()); |
|
||||||
|
|
||||||
@Pointcut("@annotation(com.zilber.boot.annotation.DataSource)" |
|
||||||
+ "|| @within(com.zilber.boot.annotation.DataSource)") |
|
||||||
public void dsPointCut() |
|
||||||
{ |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Around("dsPointCut()") |
|
||||||
public Object around(ProceedingJoinPoint point) throws Throwable |
|
||||||
{ |
|
||||||
DataSource dataSource = getDataSource(point); |
|
||||||
|
|
||||||
if (StringUtils.isNotNull(dataSource)) |
|
||||||
{ |
|
||||||
DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name()); |
|
||||||
} |
|
||||||
|
|
||||||
try |
|
||||||
{ |
|
||||||
return point.proceed(); |
|
||||||
} |
|
||||||
finally |
|
||||||
{ |
|
||||||
// 销毁数据源 在执行方法之后
|
|
||||||
DynamicDataSourceContextHolder.clearDataSourceType(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取需要切换的数据源 |
|
||||||
*/ |
|
||||||
public DataSource getDataSource(ProceedingJoinPoint point) |
|
||||||
{ |
|
||||||
MethodSignature signature = (MethodSignature) point.getSignature(); |
|
||||||
DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class); |
|
||||||
if (Objects.nonNull(dataSource)) |
|
||||||
{ |
|
||||||
return dataSource; |
|
||||||
} |
|
||||||
|
|
||||||
return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class); |
|
||||||
} |
|
||||||
} |
|
@ -1,27 +0,0 @@ |
|||||||
package com.zilber.boot.framework.datasource; |
|
||||||
|
|
||||||
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; |
|
||||||
|
|
||||||
import javax.sql.DataSource; |
|
||||||
import java.util.Map; |
|
||||||
|
|
||||||
/** |
|
||||||
* 动态数据源 |
|
||||||
* |
|
||||||
* @author lsc |
|
||||||
*/ |
|
||||||
public class DynamicDataSource extends AbstractRoutingDataSource |
|
||||||
{ |
|
||||||
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) |
|
||||||
{ |
|
||||||
super.setDefaultTargetDataSource(defaultTargetDataSource); |
|
||||||
super.setTargetDataSources(targetDataSources); |
|
||||||
super.afterPropertiesSet(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
protected Object determineCurrentLookupKey() |
|
||||||
{ |
|
||||||
return DynamicDataSourceContextHolder.getDataSourceType(); |
|
||||||
} |
|
||||||
} |
|
@ -1,45 +0,0 @@ |
|||||||
package com.zilber.boot.framework.datasource; |
|
||||||
|
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
|
|
||||||
/** |
|
||||||
* 数据源切换处理 |
|
||||||
* |
|
||||||
* @author lsc |
|
||||||
*/ |
|
||||||
public class DynamicDataSourceContextHolder |
|
||||||
{ |
|
||||||
public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class); |
|
||||||
|
|
||||||
/** |
|
||||||
* 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本, |
|
||||||
* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 |
|
||||||
*/ |
|
||||||
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>(); |
|
||||||
|
|
||||||
/** |
|
||||||
* 设置数据源的变量 |
|
||||||
*/ |
|
||||||
public static void setDataSourceType(String dsType) |
|
||||||
{ |
|
||||||
log.info("切换到{}数据源", dsType); |
|
||||||
CONTEXT_HOLDER.set(dsType); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 获得数据源的变量 |
|
||||||
*/ |
|
||||||
public static String getDataSourceType() |
|
||||||
{ |
|
||||||
return CONTEXT_HOLDER.get(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 清空数据源变量 |
|
||||||
*/ |
|
||||||
public static void clearDataSourceType() |
|
||||||
{ |
|
||||||
CONTEXT_HOLDER.remove(); |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue