一、 先定义一个注解
/**
* @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;
}