SpringBoot接口防抖的5种高效方案

 更新时间:2026年01月27日 10:07:26   作者:程序员西西  
本文主要介绍了SpringBoot接口防抖的5种高效方案,包括基于缓存、基于Token和基于注解的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

接口防抖是一种用于限制用户重复提交请求的机制。在Web开发中,用户可能会因为网络延迟或者多次点击按钮而导致多次提交同一个请求,这可能会对系统产生不必要的压力,或者导致数据异常。接口防抖就是为了解决这个问题而设计的。

接口防抖的基本原理是,在接收到一个请求后,服务器会在一定的时间内暂时忽略后续相同的请求,直到这段时间过去,才会再次处理新的请求。这样可以有效地避免重复提交导致的问题。

常见的接口防抖实现方式包括基于缓存、基于Token、基于拦截器等。在Spring Boot中,我们可以利用拦截器、过滤器或者切面等机制来实现接口防抖功能。

下面我们就来看看在SpringBoot中如何实现这些操作。

基于缓存实现防抖

这里使用了ConcurrentHashMap作为缓存来实现,当然在实际操作的时候还可以使用Redis缓存或者是Memcached来作为缓存操作。

@Component
public class DebounceInterceptor {
 
    private static final ConcurrentHashMap<String, Long> CACHE = 
      new ConcurrentHashMap<>();
    private static final long EXPIRE_TIME = 5000; // 5秒内重复请求会被拦截
 
    public boolean shouldIntercept(HttpServletRequest request) {
        String key = request.getMethod() + ":" + request.getRequestURI() + ":" 
          + request.getParameterMap();
        long now = System.currentTimeMillis();
        if (CACHE.containsKey(key)) {
            long lastRequestTime = CACHE.get(key);
            if (now - lastRequestTime < EXPIRE_TIME) {
                return true; // 请求被拦截
            }
        }
        CACHE.put(key, now);
        return false; // 请求通过
    }
}

在上面的代码中,我们使用ConcurrentHashMap来存储请求信息,其中key是请求的方法、URL和参数,value是请求的时间戳。如果同样的请求在5秒内重复出现,则会被拦截。然后,我们创建一个拦截器来应用这个防抖逻辑,如下所示。

public class DebounceInterceptor implements HandlerInterceptor {
 
    @Autowired
    private DebounceService debounceService;
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
                             Object handler) throws Exception {
        if (debounceService.shouldIntercept(request)) {
               // 返回429状态码表示请求过多
            response.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS); 
            return false;
        }
        return true;
    }
}

最后,在配置类中注册这个拦截器。如下所示。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new DebounceInterceptor()).addPathPatterns("/**");
    }
}

基于Token实现防抖

通过在请求中添加Token,在一定时间内禁止相同的Token重复提交,代码如下所示。

@Component
public class TokenInterceptor {
 
    private static final ConcurrentHashMap<String, Long> CACHE = 
      new ConcurrentHashMap<>();
    private static final long EXPIRE_TIME = 5000; // 5秒内重复Token会被拦截
 
    public boolean shouldIntercept(HttpServletRequest request) {
        String token = request.getHeader("X-Request-Token");
        if (StringUtils.isEmpty(token)) {
            return false; // 请求通过,没有Token
        }
        long now = System.currentTimeMillis();
        if (CACHE.containsKey(token)) {
            long lastRequestTime = CACHE.get(token);
            if (now - lastRequestTime < EXPIRE_TIME) {
                return true; // 请求被拦截
            }
        }
        CACHE.put(token, now);
        return false; // 请求通过
    }
}

在这种方法中,我们需要在请求头中添加一个Token,然后使用ConcurrentHashMap来存储Token和请求时间的映射关系。如果相同的Token在5秒内重复出现,则会被拦截。然后,我们创建一个拦截器来应用这个防抖逻辑,与上面的方法类似。

基于注解实现防抖

通过自定义注解来实现防抖,使得只需要在需要防抖的接口上添加注解即可。

定义注解类

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Debounce {
    long value() default 5000; // 默认5秒内重复请求会被拦截
}

创建切面类来实现拦截注解的操作。

@Aspect
@Component
public class DebounceAspect {
 
    private static final ConcurrentHashMap<String, Long> CACHE = 
      new ConcurrentHashMap<>();
 
    @Autowired
    private HttpServletRequest request;
 
    @Around("@annotation(debounce)")
    public Object debounce(ProceedingJoinPoint joinPoint, Debounce debounce) 
throws Throwable {
        String key = request.getMethod() + ":" + request.getRequestURI() + ":" 
          + request.getParameterMap();
        long now = System.currentTimeMillis();
        if (CACHE.containsKey(key)) {
            long lastRequestTime = CACHE.get(key);
            if (now - lastRequestTime < debounce.value()) {
                return null; // 请求被拦截
            }
        }
        CACHE.put(key, now);
        return joinPoint.proceed(); // 请求通过
    }
}

最后,在启动类上添加@EnableAspectJAutoProxy注解,启用切面代理功能。

总结

以上是几种常见的Spring Boot接口防抖的实现方案,你可以根据具体情况选择适合你的方案,并根据需求进行定制和扩展。

到此这篇关于SpringBoot接口防抖的5种高效方案的文章就介绍到这了,更多相关SpringBoot接口防抖内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Linux系统中查询JDK安装目录的几种常用方法

    Linux系统中查询JDK安装目录的几种常用方法

    这篇文章主要介绍了Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目录搜索,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-07-07
  • SpringBoot3 spring.factories自动配置功能不生效的解决

    SpringBoot3 spring.factories自动配置功能不生效的解决

    SpringBoot3弃用spring.factories,改用AutoConfiguration.imports文件管理自动配置类,需删除旧文件,新增专用文件并使用@AutoConfiguration替代@Configuration+@ConditionalOn组合注解,提升配置清晰度与未来扩展性
    2025-09-09
  • Java高效映射工具MapStruct的使用示例

    Java高效映射工具MapStruct的使用示例

    MapStruct 是一个 Java 注解处理器,用于在不同 Java Beans 或数据传输对象(DTOs)之间自动生成类型安全的映射代码,这是一个编译时映射框架,意味着它利用注解在编译时生成代码,本文将给大家介绍一下Java注解处理器MapStruct的使用示例,需要的朋友可以参考下
    2023-12-12
  • Springboot如何使用Aspectj实现AOP面向切面编程

    Springboot如何使用Aspectj实现AOP面向切面编程

    这篇文章主要介绍了Springboot如何使用Aspectj实现AOP面向切面编程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Spring详细讲解7种事务传播方式

    Spring详细讲解7种事务传播方式

    Spring事务传播机制是指,包含多个事务的方法在相互调用时,事务是如何在这些方法间传播的。本文通过示例详细介绍了Spring的事务传播机制,需要的可以参考一下
    2023-01-01
  • IntelliJ IDEA无公网远程Linux服务器环境开发过程(推荐收藏)

    IntelliJ IDEA无公网远程Linux服务器环境开发过程(推荐收藏)

    下面介绍如何在IDEA中设置远程连接服务器开发环境并结合Cpolar内网穿透工具实现无公网远程连接,然后实现远程Linux环境进行开发,感兴趣的朋友跟随小编一起看看吧
    2023-12-12
  • Java数组动态扩容的实现示例

    Java数组动态扩容的实现示例

    本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-12-12
  • Spring菜鸟教你看源码冲面试

    Spring菜鸟教你看源码冲面试

    这篇文章主要介绍了Spring菜鸟教你看源码冲面试,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • 详细分析Java并发集合ArrayBlockingQueue的用法

    详细分析Java并发集合ArrayBlockingQueue的用法

    这篇文章主要介绍了详细分析Java并发集合ArrayBlockingQueue的用法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • MyBatis SqlSession执行流程小结

    MyBatis SqlSession执行流程小结

    本文主要介绍了MyBatis SqlSession执行流程小结,涵盖动态代理、Executor、StatementHandler等组件,及参数处理、结果映射与缓存机制,感兴趣的可以了解一下
    2025-05-05

最新评论