1、新建一个自定义注解 RepeatSubmit
import java.lang.annotation.*;
/**
* 放重复提交
* @author LenMotion
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RepeatSubmit {
// 限制时间 秒
long limitTime();
String message() default "请勿重复提交";
}
2、新建对应Aspect类
/**
* @author LenMotion
*/
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class RepeatSubmitAspect {
private final RedissonClient redissonClient;
private final HttpServletRequest request;
@Around(value = "@annotation(repeatSubmit)")
public Object around(ProceedingJoinPoint joinPoint, RepeatSubmit repeatSubmit) throws Throwable {
var token = request.getHeader(BaseConstant.AUTH_HEADER);
var uri = request.getRequestURI();
var key = "repeatSubmit:" + uri + ":" + token;
// 分布式锁
RLock lock = redissonClient.getLock(key);
log.info("防重复提交加锁 {}", key);
// 尝试加锁,最多等待0秒,上锁以后 x 秒自动解锁
if (lock.tryLock(0, repeatSubmit.limitTime(), TimeUnit.SECONDS)) {
return joinPoint.proceed();
}
throw new BusinessException(ResponseCodeEnum.LOCK_ERROR, repeatSubmit.message());
}
}