前言

在理论开发过程中,web利用常常会呈现网络提早,接口解决工夫略长,用户习惯等起因造成的客户间断屡次点击提交按钮调用接口,导致数据库会呈现反复数据或这接口业务逻辑bug等问题

计划

利用redis锁实同一个用户同一个申请2秒内反复提交返回谬误路由

SubmitLock

标记须要拦挡的办法

@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documented@Inheritedpublic @interface SubmitLock {    int expire() default 2;}

RedisLockUtil

redis锁校验及写入

@Componentpublic class RedisLockUtil {    @Autowired    private RedisUtil redisUtil;    private int lockDBIndex = 1;    public boolean lock(String key,String clientID,int lockExpire){       if(redisUtil.isValid(key,lockDBIndex)){            return false;       }else{           redisUtil.redisTemplateSet(key,clientID,lockDBIndex);           redisUtil.setExpire(key,lockExpire, TimeUnit.SECONDS,lockDBIndex);           return true;       }    }}

RepeatSubmitAspect

对立拦挡切面

@Aspect@Component@Order(value = 100)public class RepeatSubmitAspect {    private static Logger logger = LoggerFactory.getLogger(RepeatSubmitAspect.class);    @Autowired    private RedisLockUtil redisLockUtil;    /**     * 切面点 指定注解     */    @Pointcut("@annotation(com.haopan.frame.common.annotation.SubmitLock) " +            "|| @within(com.haopan.frame.common.annotation.SubmitLock)")    public void repeatSubmitAspect() {    }    /**     * 拦挡办法指定为 repeatSubmitAspect     */    @Around("repeatSubmitAspect()")    public Object around(ProceedingJoinPoint point) throws Throwable {        MethodSignature signature = (MethodSignature) point.getSignature();        Method method = signature.getMethod();        SubmitLock submitLock = method.getAnnotation(SubmitLock.class);        if (submitLock != null) {            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();            HttpServletRequest request = requestAttributes.getRequest();            String token = request.getHeader("token");            if (!StringUtil.isEmpty(token)) {                String path = request.getServletPath();                String key = "submitLock|" + token + "|" + path;                String clientId = CommonUtil.getNewGuid();                if (redisLockUtil.lock(key, clientId, submitLock.expire())) {                    // 获取锁胜利                    return point.proceed();                } else {                    System.out.println("tryLock fail, key = ["+key+"]");                    return Result.errorResult().setMsg("反复申请,请稍后再试").setCode(-980);                }            } else {                return point.proceed();            }        } else {            return point.proceed();        }    }}