1.定义一个注解
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.自定义aop切面类
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.如何使用
@RestController
@RequestMapping("/repeat")
public class RepeatController {
@GetMapping("/test")
@RepeatAnnotation
public Object test() {
return "成功";
}
}
测试的结果