spring Aop实现防止重复提交

一、 先定义一个注解

/**
 * @desc    定义一个不重复提交的注解
 * @author  x了个w 
 * @create  2020年07月02日15:55:07
 */
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NoRepeatSubmit {


    /**
     * 防止重复参数默认值
     * @return
     */
    String value() default "";

    /**
     * 过期时间
     * @return
     */
    int milliseconds()  default 1;
} 

二、实现一个aop

/**
 * @author x了个w 
 * @desc 分布式,防重复操作异常捕获
 * @create 2020年07月02日17:40:42
 */
@Aspect
@Component
@Log4j2
public class RepeatSubmitAspect {

    @Autowired
    private RedisUtil redisUtil;

    @Pointcut("@annotation(NoRepeatSubmit)")
    public void pointCut() {
    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint pjp) {
        Object result = null;
        StringBuilder sb = new StringBuilder();


        // 拦截的实体类
        Object target = pjp.getTarget();
        //获取类名
        String className = target.getClass().getName();

        sb.append(className);


        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();

        //获得注解
        NoRepeatSubmit noRepeatSubmit = method.getAnnotation(NoRepeatSubmit.class);


        // 拦截的方法名称。当前正在执行的方法
        String methodName = method.getName();

        sb.append(methodName);

        // 拦截的方法参数
        Object[] args = pjp.getArgs();


        for (Object arg : args) {
            if (arg == null) {
                continue;
            }
            int code = arg.hashCode();
            sb.append("#");
            sb.append(code);
        }


        String value = noRepeatSubmit.value();
        if (StringUtils.isEmpty(value)) {
            value = sb.toString();
        }

     //获取过期时间
        int milliseconds = noRepeatSubmit.milliseconds();
        try {

            long count = redisUtil.incr(value, 1);

            redisUtil.expire(value, milliseconds);

            if (count > 1) {
                System.out.println(count);
                //重复提交
                CommonDto dto = new CommonDto();
                dto.setCode(500);
                dto.setMsg("您的操作过快,请刷新重试");
                return dto;
            }
            
        } catch (Exception e) {
            redisUtil.del(value);
            log.error("redis加锁异常", e);
            throw new BusinessException(e.getMessage());
        }


        try {
            //执行原来方法
            result = pjp.proceed();
        } catch (Throwable e) {
            log.error("分布式防重复操作异常Throwable::" + e.getMessage());
            e.printStackTrace();
            throw new BusinessException(e.getMessage());
        }
        return result;
    }

你可能感兴趣的:(spring Aop实现防止重复提交)