NoRepeatSubmitAop
import java.lang.annotation.*;
/**
* [防重复提交注解]</p >
* @author chenp
* @date 2024/1/8
*/
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented
public @interface NoRepeatSubmit {
/**
* 缓存的key
* @return {@link String}
*/
String key() default "";
/**
* 参数名称集合
*
* @return {@link String}
*/
String[] args() default "";
ResultCodesEnum defaultMsg() default ResultCodesEnum.ERROR_DEVICE_DAY_BEING_ERROR;
/**
* 存活时间
*/
long survivalTime() default 60;
}
NoRepeatSubmit
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
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.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* @author chenp
* @date 2024/1/8
*/
@Component
@Aspect
@Slf4j
public class NoRepeatSubmitAop {
@Resource
private RedissonClient redissonClient;
/**
* @Title: queryCachePointcut
* @Description: 定义切点为缓存注解
* @return void
**/
@Pointcut("@annotation(com.......NoRepeatSubmit)")
public void queryCachePointcut(){
}
@Around(value = "queryCachePointcut()&&@annotation(noRepeatSubmit)")
public Object Interceptor(ProceedingJoinPoint joinPoint, NoRepeatSubmit noRepeatSubmit) throws Throwable{
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//参数名
String[] parameterNames = signature.getParameterNames();
//参数值
Object[] method_args = joinPoint.getArgs();
String[] args = noRepeatSubmit.args();
String params = ":";
if(Objects.nonNull(args) && args.length>0 && Objects.nonNull(parameterNames) && parameterNames.length>0){
for(int i=0;i<args.length;i++){
String[] split = args[i].split("\.");
for(int j=0;j<parameterNames.length;j++){
if(split[0].equals(parameterNames[j])){
if(split.length>1){
JSONObject jsonObject = (JSONObject) JSON.toJSON(method_args[j]);
params = params+jsonObject.get(split[1]);
}else{
params = params+method_args[j];
}
}
}
}
}else{
params = params+method_args;
}
String key = noRepeatSubmit.key() + params;
long survivalTime = noRepeatSubmit.survivalTime();
// 获取分布式锁
RLock lock = redissonClient.getLock(key);
try {
if (lock.tryLock(1,survivalTime,TimeUnit.SECONDS)) {
// 执行关键业务逻辑
log.info("获取到锁{},key:{}", lock.getName(),key);
return joinPoint.proceed();
} else {
// 未获取到锁,处理失败逻辑
log.info("未获取到锁");
return ResultVOUtil.error(noRepeatSubmit.defaultMsg());
}
}catch (Exception e){
return ResultVOUtil.error();
} finally {
if (null != lock && lock.isLocked()) { // 是否还是锁定状态
if (lock.isHeldByCurrentThread()) {//是否是当前执行线程的锁
log.info("释放锁{}", lock.getName());
lock.unlock(); // 释放锁
}
}
}
}
}