当前位置:   article > 正文

使用SpringBoot自定义注解+AOP+redis来实现防接口幂等性重复提交_springboot自定义注解+aop+redis实现防接口幂等性重复提交

springboot自定义注解+aop+redis实现防接口幂等性重复提交

前提:整合好springboot + redis环境,可参考博文
springboot 整合redis-CSDN博客

0 添加aop依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-aop</artifactId>
  4. </dependency>

1 编写自定义注解,注解的作用是标记一个方法是否支持幂等性

  1. import java.lang.annotation.ElementType;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.annotation.Target;
  5. @Target(ElementType.METHOD)
  6. @Retention(RetentionPolicy.RUNTIME)
  7. public @interface Idempotent {
  8. long expire() default 2L;
  9. }

2 AOP切面逻辑,来判断一个方法是否被标记了该注解。如果被标记了该注解,那么就需要对该方法进行特殊处理,以实现幂等性

  1. @Aspect
  2. @Component
  3. public class IdempotentAspect {
  4. private final RedisTemplate redisTemplate;
  5. @Autowired
  6. public IdempotentAspect(RedisTemplate redisTemplate) {
  7. this.redisTemplate = redisTemplate;
  8. }
  9. @Around("@annotation(com.example.demo.annotation.Idempotent)")
  10. public Object idempotent(ProceedingJoinPoint joinPoint) throws Throwable {
  11. // 获取请求参数
  12. Object[] args = joinPoint.getArgs();
  13. // 获取请求方法
  14. MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  15. Method method = signature.getMethod();
  16. // 获取注解信息
  17. Idempotent idempotent = method.getAnnotation(Idempotent.class);
  18. String key = getKey(joinPoint);
  19. // 判断是否已经请求过
  20. if (redisTemplate.hasKey(key)) {
  21. throw new RuntimeException("请勿重复提交");
  22. }
  23. // 标记请求已经处理过
  24. redisTemplate.opsForValue().set(key, "1", idempotent.expire(), TimeUnit.SECONDS);
  25. // 处理请求
  26. return joinPoint.proceed(args);
  27. }
  28. /**
  29. * 获取redis key
  30. */
  31. private String getKey(ProceedingJoinPoint joinPoint) {
  32. MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  33. Method method = signature.getMethod();
  34. String methodName = method.getName();
  35. String className = joinPoint.getTarget().getClass().getSimpleName();
  36. Object[] args = joinPoint.getArgs();
  37. StringBuilder sb = new StringBuilder();
  38. sb.append(className).append(":").append(methodName);
  39. for (Object arg : args) {
  40. sb.append(":").append(arg.toString());
  41. }
  42. return sb.toString();
  43. }
  44. }

3 示例测试

  1. @RestController
  2. public class DemoController {
  3. @Autowired
  4. private TBookOrderMapper tBookOrderMapper;
  5. @GetMapping("/demo")
  6. @Idempotent(expire = 60)
  7. public String demo(@RequestBody TBookOrder tBookOrder) {
  8. // 处理请求
  9. int insert = tBookOrderMapper.insert(tBookOrder);
  10. return insert==1?"ok":"wrong";
  11. }
  12. }

参考博文
SpringBoot自定义注解+AOP+redis实现防接口幂等性重复提交,从概念到实战_aop防重复提交-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/459589
推荐阅读
相关标签
  

闽ICP备14008679号