一.文章结构
1.页面防重复提交实现方式(按钮置灰治标不治本,主键判断高并发下失效,基于redis单线程实现)
2.项目集成(开箱即用,maven引入,方法加注解)
3.多线程快速点击结果展示
4.实现原理剖析(自定义注解,spring的aop拦截,redis的setNx的使用)
5.源码下载
二.防重复提交组件集成
1.maven引入
<dependency>
<groupId>com.zenglx.assembly</groupId>
<artifactId>avoidRepeatSubmit</artifactId>
</dependency>
2.方法加注解
@PostMapping("/testRepeatSubmit")
@RepeatSubmit
@ApiOperation(value = "测试重复提交", notes = "返回结果")
public String testRepeatSubmit(@RequestBody String param) {
System.out.println("重复提交测试");
return null;
}
三.多线程快速点击结果展示
四.实现原理剖析
1.自定义注解
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RepeatSubmit {
}
@Before("@annotation(com.zenglx.assembly.avoidRepeatSubmit.RepeatSubmit)")
public void beforeCheck(JoinPoint joinPoint) {
Long start = System.currentTimeMillis();
Object[] objects = joinPoint.getArgs();
//这种情况加入参数校验 10s过期
if (objects.length == 1) {
if (setNx(String.valueOf(objects[0].hashCode()))) {
expireByMilliseconds(String.valueOf(objects[0].hashCode()), 10L);
log.info("check time : " + (System.currentTimeMillis() - start) + "ms");
} else {
log.error("RepeatSubmit repeat: " + joinPoint.toLongString());
throw new RepeatSubmitException("请不要重复提交");
}
}
}
2.redis单线程setNx
放入值和获取值是原子性的