步骤
- 创建一个注解类
注意两个参数;
1. target 目标类行 方法/类?
2. Retention 生效策略
-
编写切面逻辑
-
类上注解打起来 @Aspect
-
切点注解打起来,规则配起来@Pointcut("@annotation(com.example.chaoming.exercise.jdk.aop.Retryable)")
-
@Around(切点) 写增强逻辑
-
执行切点的proceed 方法
应用 (动态数据源)
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.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.kedacom.ctsp.syncdata.utils.StringUtils;
import java.lang.reflect.Method;
@Aspect
@Order(1)
@Component
public class DataSourceAspect {
@Pointcut("@annotation(com.kedacom.ctsp.syncdata.annotation.DataSource) || @within(com.kedacom.ctsp.syncdata.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();
Class<? extends Object> targetClass = point.getTarget().getClass();
DataSource targetDataSource = targetClass.getAnnotation(DataSource.class);
if (StringUtils.isNotNull(targetDataSource)) {
return targetDataSource;
} else {
Method method = signature.getMethod();
DataSource dataSource = method.getAnnotation(DataSource.class);
return dataSource;
}
}
}
public class DynamicDataSourceContextHolder {
public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);
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();
}
}