说明:实际开发中,我们前端页面点击一个按钮访问一个接口,这时因为网络波动或者其他原因页面没有反应,用户可能会在短时间内再次点击一次或者用户以为没有点到,很快的又点了一次。导致短时间发送两个请求后台可能会导致数据重复添加

为了避免短时间内对一个接口访问,我们可以通过AOP+自定义注解+Redis方式,在接口加一自定义注解然后通过AOP的前置通知,在Redis中存入一个有效期的值,当访问接口这个值还未过期,则抛出异常,以此来避免短时间对接口方法

实现

一步创建一个自定义注解设置两个属性,一个是key,一个是这个key在Redis中的有效时间

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LimitAccess {

    /**
     * 限制访问的key
     * @return
     */
    String key();

    /**
     * 限制访问时间
     * @return
     */
    int times();
}

第二步:创建对应的Aspect

import com.hezy.annotation.LimitAccess;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
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.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;

/**
 * AOP类(通知类)
 */
@Component
@Aspect
public class LimitAspect {

    @Autowired
    private RedisTemplate redisTemplate;

    @Pointcut("@annotation(com.hezy.annotation.LimitAccess)")
    public void pt(){};

    @Around("pt()")
    public Object aopAround(ProceedingJoinPoint pjp) throws Throwable {
        // 获取切入点上面的自定义注解
        Signature signature = pjp.getSignature();

        MethodSignature methodSignature = (MethodSignature) signature;

        // 获取方法上面的注解
        LimitAccess limitAccess = methodSignature.getMethod().getAnnotation(LimitAccess.class);

        // 获取注解上面的属性
        int limit = limitAccess.times();
        String key = limitAccess.key();

        // 根据key去找Redis中的值
        Object o = redisTemplate.opsForValue().get(key);

        // 如果不存在说明是首次访问,存入Redis,过期时间limitAccess中的time
        if (o == null) {
            redisTemplate.opsForValue().set(key, "", limit, TimeUnit.SECONDS);
            // 执行切入点的方法
            return pjp.proceed();
        } else {
            // 如果存在说明不是首次访问,抛出异常
            throw new RuntimeException("访问过于频繁");
        }
    }
}

第三步:在需要限制接口上,加上这个注解,并设置key和限制访问时间如下这个这个接口设置key为set,实际开发可以设置一个随机值,或者按照规则自定义设置,times限制访问时间

    @GetMapping("/limit")
    @LimitAccess(key = "limit", times = 10)
    public String limit() {
        return "success";
    }

演示

启动项目,访问该接口

(首次访问,没得问题,同时在Redis中存入值)

在这里插入图片描述


(短时间内,连续访问,因为Redis中值未过期

在这里插入图片描述

在这里插入图片描述


(10秒之后再访问,又可以了,Redis中的值过期了)

在这里插入图片描述

以上就是使用Redis实现接口防抖,避免短时间内连续访问接口。实际开发中,可以异常设置为自定义异常

原文地址:https://blog.csdn.net/qq_42108331/article/details/134691925

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_35670.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注