springboot implements redis anti-repetitive submission based on custom annotation method

1. Define an annotation

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;

/**
 * @author 
 * ClassName:RepeatAnnotation.java
 * date:2022-07-09 15:02
 * Description: 防重复提交注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RepeatAnnotation {

    /**
     * 重复提交间隔时间
     * @return
     */
    long timeout() default 3000;

    /**
     * 时间单位 默认毫秒
     * @return
     */
    TimeUnit unit() default TimeUnit.MILLISECONDS;
}

2. Customize aop aspect class

import cn.hutool.core.util.ObjectUtil;
import com.repeat.anno.RepeatAnnotation;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @author 
 * ClassName:RepeatAnnoAspect.java
 * date:2022-07-09 15:09
 * Description: 注解切面类
 */
@Aspect
@Component
@Slf4j
@AllArgsConstructor
public class RepeatAnnoAspect {
    private final RedisTemplate redisTemplate;

    /**
     * @annotation(注解类所在路径)
     */
    @Pointcut("@annotation(com.repeat.anno.RepeatAnnotation)")
    public void repeatCommitPointCut() {

    }

    /**
     * 获取方法上注解
     */
    @Around("repeatCommitPointCut()")
    @SneakyThrows
    public Object repeatCommitAround(ProceedingJoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        // 获取注解
        RepeatAnnotation annotation = method.getAnnotation(RepeatAnnotation.class);
        System.out.println(annotation);
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String requestURI = request.getRequestURI();
        String methods = request.getMethod();
        System.out.println(String.format("请求路径:%s", requestURI));
        System.out.println(String.format("请求方式:%s", methods));
        String redisKey = requestURI + ":" + methods;
        // redis数据
        Object commit = redisTemplate.opsForValue().get(redisKey);
        if (ObjectUtil.isNotEmpty(commit)) {
            return "重复提交数据";
        }
        // 未提交过数据
        redisTemplate.opsForValue().set(redisKey, "11231", annotation.timeout(), annotation.unit());
        Object proceed = joinPoint.proceed();
        return proceed;

    }


}

3.How to use

@RestController
@RequestMapping("/repeat")
public class RepeatController {
    @GetMapping("/test")
    @RepeatAnnotation
    public Object test() {
        return "成功";
    }

}

Test results

Insert image description here

Insert image description here

 

 

Guess you like

Origin blog.csdn.net/weixin_41018853/article/details/126030034