//@NoRepeatSubmit
package com.box.lock.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;
/**
* 文件描述
*
* @author yuan.dingwang
* @date 2021年03月03日 17:51
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NoRepeatSubmit {
/**
* 过期秒数,默认为5毫秒
*
* @return 轮询锁的时间
*/
int expire() default 2000;
/**
* 超时时间单位
*
* @return 毫秒
*/
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
}
package com.box.lock.aspect;
import com.box.common.core.constant.CacheKeyConstant;
import com.box.common.core.enums.ErrorCodeEnum;
import com.box.common.core.exception.AuthException;
import com.box.common.core.login.BaseLoginInfo;
import com.box.common.core.login.RedLoginInfo;
import com.box.lock.annotation.NoRepeatSubmit;
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.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* 接口重复提交处理类
*
* @author yuan.dingwang
* @date 2021年03月03日 17:52
*/
@Slf4j
@Aspect
@Component
public class RepeatSubmitAspect {
@Autowired
private RedissonClient redissonClient;
@Pointcut("@annotation(noRepeatSubmit)")
public void pointCut(NoRepeatSubmit noRepeatSubmit) {
}
@Around("pointCut(noRepeatSubmit)")
public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable {
log.info("验证是否重复请求生效");
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
BaseLoginInfo loginInfo = RedLoginInfo.getUser(request);
String method = pjp.getSignature().getName();
StringBuffer key = new StringBuffer(CacheKeyConstant.CECHE_LOCK_REPEAT_SUBMIT).append(method).append("_").append(loginInfo.getId());
RLock rLock = redissonClient.getLock(key.toString());
rLock.lock(noRepeatSubmit.expire(), noRepeatSubmit.timeUnit());
log.info("获取到锁状态:{}",rLock.isLocked());
if (rLock.isLocked()) {
// 获取锁成功
Object result;
try {
// 执行进程
//Thread.sleep(4000);
//log.info("获取到锁状态2:{}",rLock.isLocked());
result = pjp.proceed();
} finally {
// 解锁
if(rLock.isLocked()) {
rLock.unlock();
}
}
return result;
} else {
//return Result.fail(ErrorCodeEnum.CHECK_REPEAT_SUBMIT);
throw new AuthException(ErrorCodeEnum.CHECK_REPEAT_SUBMIT);
}
}
private String getKey(String token, String path) {
return token + path;
}
}