SpringBoot自定义注解+AOP+redis实现防接口幂等性重复提交,从概念到实战

这篇具有很好参考价值的文章主要介绍了SpringBoot自定义注解+AOP+redis实现防接口幂等性重复提交,从概念到实战。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文为千锋教育技术团独家创作,更多技术类知识干货,点个关注持续追更~

接口幂等性是Web开发中非常重要的一个概念,它可以保证多次调用同一个接口不会对结果产生影响。如果你想了解更多关于接口幂等性的知识,那么本文就是一个不错的起点。

在Web开发中,我们经常需要防止用户重复提交某个操作,尤其是一些需要保证数据一致性的操作,如支付等。而接口幂等性就是解决这个问题的一种方案。

接口幂等性指的是:无论调用多少次同一个接口,最终的结果都是一致的。如果接口不具备幂等性,那么多次调用可能会导致数据的不一致性,甚至产生莫名其妙的错误。**

那么,如何实现接口幂等性呢?

本文小岳将给大家介绍一种实现方案,即:使用SpringBoot自定义注解+AOP+redis来实现防接口幂等性重复提交。

1. 概念解析

1.1 接口幂等性

接口幂等性是指:同一个接口的多次调用,最终的结果都是一致的。这意味着,无论调用多少次接口,最终的结果都应该是相同的。这是因为接口的幂等性保证了多次调用接口不会对结果产生影响。

在Web开发中,保证接口幂等性非常重要。

例如, 假设我们有一个接口用来修改用户信息,那么该接口应该具备幂等性。如果用户多次调用该接口,那么最终的结果都应该是一致的,即用户信息被修改成功。如果接口不具备幂等性,那么多次调用可能会导致数据的不一致性,甚至产生莫名其妙的错误。

为了实现接口的幂等性,我们可以使用一些技术手段,例如使用Token或者在服务端存储请求的处理状态。这些技术手段可以确保同一个请求只会被处理一次,从而保证接口的幂等性。

总之,接口幂等性是Web开发中非常重要的一个概念,它可以保证多次调用同一个接口不会对结果产生影响。因此,我们在开发过程中需要注意保证接口的幂等性,以确保系统的稳定性和数据的一致性。

1.2 防重复提交

防重复提交是指系统要能够识别出用户重复提交某个操作,并且不会再次执行该操作。这是为了避免数据的不一致性和重复操作产生的问题。

在本文中,我们使用自定义注解@Idempotent、AOP和Redis来实现防接口幂等性重复提交。

当一个请求被处理过后,我们会将请求的处理状态存储到Redis中,并设置一个过期时间,以保证不会一直占用Redis的内存空间。来看示例代码:

@RestController
public class DemoController {

    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/demo")
    @Idempotent(expire = 60)
    public String demo(@RequestParam("id") Long id) {
        if (redisTemplate.hasKey("demo:" + id)) {
            return "请勿重复提交";
        }
        // 处理请求
        redisTemplate.opsForValue().set("demo:" + id, "1", 60, TimeUnit.SECONDS);
        return "success";
    }
}

在上面的代码中,我们在demo方法上使用了自定义注解@Idempotent,并设置了过期时间为60秒。当一个请求被处理过后,我们会将请求的处理状态存储到Redis中,以保证在60秒内不会再次执行该操作。如果用户重复提交该操作,那么系统会返回请勿重复提交的提示。这样就可以有效地避免接口重复提交产生的问题。

需要注意的是,为了防止多次请求同时到达服务器,导致多次同时处理,我们需要在Redis中加锁,可以使用Redis的setnx命令或者分布式锁来实现。另外,为了保证幂等性,我们需要保证请求是幂等的,即多次请求的结果都是一致的。如果请求不是幂等的,那么我们需要对请求进行去重处理,以保证只有一个请求被处理。

2. 实现方案

2.1 自定义注解

为了实现接口的幂等性,我们需要先定义一个自定义注解。注解的作用是标记一个方法是否支持幂等性。如果支持幂等性,那么就需要对该方法进行特殊处理,使得多次调用该方法不会对结果产生影响。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Idempotent {
}

2.2 AOP切面

我们可以使用AOP来判断一个方法是否被标记了@Idempotent注解。如果被标记了注解,那么就需要对该方法进行特殊处理,以实现幂等性。

@Aspect
@Component
public class IdempotentAspect {

    private final RedisTemplate redisTemplate;

    @Autowired
    public IdempotentAspect(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Around("@annotation(com.example.demo.annotation.Idempotent)")
    public Object idempotent(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取请求参数
        Object[] args = joinPoint.getArgs();
        // 获取请求方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        // 获取注解信息
        Idempotent idempotent = method.getAnnotation(Idempotent.class);
        String key = getKey(joinPoint);
        // 判断是否已经请求过
        if (redisTemplate.hasKey(key)) {
            throw new RuntimeException("请勿重复提交");
        }
        // 标记请求已经处理过
        redisTemplate.opsForValue().set(key, "1", idempotent.expire(), TimeUnit.SECONDS);
        // 处理请求
        return joinPoint.proceed(args);
    }

    /**
     * 获取redis key
     */
    private String getKey(ProceedingJoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        String methodName = method.getName();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        Object[] args = joinPoint.getArgs();
        StringBuilder sb = new StringBuilder();
        sb.append(className).append(":").append(methodName);
        for (Object arg : args) {
            sb.append(":").append(arg.toString());
        }
        return sb.toString();
    }
}

2.3 Redis存储

我们使用Redis来存储请求的处理状态。当一个请求被处理过后,我们会将请求的处理状态存储到Redis中,并设置一个过期时间,以保证不会一直占用Redis的内存空间。

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        return redisTemplate;
    }
}

2.4 示例代码

下面是一个示例代码,该代码演示了如何使用@Idempotent注解来实现接口的幂等性。

@RestController
public class DemoController {

    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/demo")
    @Idempotent(expire = 60)
    public String demo(@RequestParam("id") Long id) {
        // 处理请求
        return "success";
    }
}

3. 总结

本文介绍了如何使用SpringBoot自定义注解+AOP+redis来实现防接口幂等性重复提交

我们首先定义了一个自定义注解@Idempotent,然后使用AOP来判断一个方法是否被标记了该注解。如果被标记了该注解,那么就需要对该方法进行特殊处理,以实现幂等性。最后,我们使用Redis来存储请求的处理状态,并设置一个过期时间,以保证不会一直占用Redis的内存空间。


以上就是本文的全部内容,更多技术类干货,点我主页持续追更~ 大家如果有技术类问题,欢迎和我们一起交流讨论

祝天天开心!文章来源地址https://www.toymoban.com/news/detail-439028.html

到了这里,关于SpringBoot自定义注解+AOP+redis实现防接口幂等性重复提交,从概念到实战的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • redis + AOP + 自定义注解实现接口限流

    限流(rate limiting) ​ 是指在一定时间内,对某些资源的访问次数进行限制,以避免资源被滥用或过度消耗。限流可以防止服务器崩溃、保证用户体验、提高系统可用性。 限流的方法有很多种,常见的有以下几种: 漏桶算法: ​漏桶算法通过一个固定大小的漏桶来模拟流量

    2024年02月03日
    浏览(24)
  • springboot自定义注解+aop+redis实现延时双删

    redis作为用的非常多的缓存数据库,在多线程场景下,可能会出现数据库与redis数据不一致的现象 数据不一致的现象:https://blog.csdn.net/m0_73700925/article/details/133447466 这里采用aop+redis来解决这个方法: 删除缓存 更新数据库 延时一定时间,比如500ms 删除缓存 这里之所以要延时一

    2024年01月17日
    浏览(32)
  • springboot3使用自定义注解+AOP+redis优雅实现防重复提交

      ⛰️个人主页:     蒾酒 🔥 系列专栏 :《spring boot实战》 🌊 山高路远,行路漫漫,终有归途 目录 写在前面 实现思路 实现步骤 1.定义防重复提交注解 2.编写一个切面去发现该注解然后执行防重复提交逻辑 3.测试 依赖条件 1.接口上标记防重复提交注解 2.接口测试 写在最

    2024年04月11日
    浏览(32)
  • redis如何保证接口的幂等性

    背景 如何防止接口中同样的数据提交,以及如何保证消息不被重复消费,这些都是 shigen 在学习的过程中遇到的问题。今天,趁着在学习 redis 的间隙,我写了一篇文章进行简单的实现。 注意:仅使用于单机的场景,对于分布式、高并发场景,还是建议使用分布式锁。 首先我

    2024年02月09日
    浏览(30)
  • redis+token+分布式锁确保接口的幂等性

    目录 1.幂等性是什么? 2.如何实现幂等性呢? 1.新增管理员,出弹窗的同时,请求后台。 2.后端根据雪花算法生成唯一标识key,以雪花数为key存到redis。并返回key给前端。 3.前端保存后端传过来的key。 4.前端输入完成信息,点击【保存】,携带key请求后端。 5.请求到达后端,

    2024年02月14日
    浏览(36)
  • SpringBoot定义拦截器+自定义注解+Redis实现接口防刷(限流)

    在拦截器Interceptor中拦截请求 通过地址+请求uri作为调用者访问接口的区分在Redis中进行计数达到限流目的 定义参数 访问周期 最大访问次数 禁用时长 代码实现 定义拦截器:实现HandlerInterceptor接口,重写preHandle()方法 注册拦截器:配置类实现WebMvcConfigurer接口,重写addIntercep

    2024年02月05日
    浏览(43)
  • 腾讯二面:如何保证接口幂等性?高并发下的接口幂等性如何实现?

    什么是接口幂等性 接口幂等性这一概念源于数学,原意是指一个操作如果连续执行多次所产生的结果与仅执行一次的效果相同,那么我们就称这个操作是幂等的。在互联网领域,特别是在Web服务、API设计和分布式系统中,接口幂等性具有非常重要的意义。 具体到HTTP接口或者

    2024年03月19日
    浏览(35)
  • 分布式接口幂等性设计实现

    面对分布式架构和微服务复杂的系统架构和网络超时服务器异常等带来的系统稳定性问题,分布式接口的幂等性设计显得尤为重要。本文简要介绍了几种分布式接口幂等性设计实现,包括Token去重机制、乐观锁机制、数据库主键和状态机实现等,以加深理解。 1、分布式接口幂

    2024年02月05日
    浏览(28)
  • Spring Boot 实现接口幂等性的 4 种方案

    现在的系统或平台,为了追求体验性、内容丰富性,都是前后端分离,系统为了解藕会引入各种MQ等,都不可避免就引入了数据幂等性的问题。 幂等是一个数学与计算机学概念,在数学中某一运算为幂等时,其作用在任一元素两次会和其作用一次的结果相同。 在计算机编程中

    2024年02月06日
    浏览(36)
  • rabbitmq+springboot实现幂等性操作

    文章目录 1.场景描述 1.1 场景1 1.2 场景2 2.原理 3.实战开发 3.1 建表 3.2 集成mybatis-plus 3.3 集成RabbitMq 3.3.1 安装mq 3.3.2 springBoot集成mq 3.4 具体实现 3.4.1 mq配置类 3.4.2 生产者 3.4.3 消费者 消息中间件是分布式系统常用的组件,无论是异步化、解耦、削峰等都有广泛的应用价值。我们

    2024年02月10日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包