天天看点

分布式页面防重复提交组件start一.文章结构二.防重复提交组件集成三.多线程快速点击结果展示 四.实现原理剖析五.源码地址

一.文章结构

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;
    }
           

三.多线程快速点击结果展示

分布式页面防重复提交组件start一.文章结构二.防重复提交组件集成三.多线程快速点击结果展示 四.实现原理剖析五.源码地址

 四.实现原理剖析

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

    放入值和获取值是原子性的

五.源码地址

https://download.csdn.net/download/zengliangxi/21458092