AOP + 自定义注解 + Redis 实现接口防刷
自定义注解:
Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyPrevent {
/**
* redis 缓存前缀,用来区分是哪个方法(有可能有多个方法被注解)
*/
String prefix();
/**
* 过期时间
*/
int expire() default 1;
/**
* 过期单位
*/
TimeUnit timeUnit() default TimeUnit.SECONDS;
}
AOP:
@Aspect
@Configuration
public class MyPreventAspect {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Around("@annotation(com.zzc.hardcore.annotation.MyPrevent)")
public Object interceptor(ProceedingJoinPoint pjp) {
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
MyPrevent myPrevent = method.getAnnotation(MyPrevent.class);
// 用户Id 是可以获取得到的
String userId = "666666";
String prefix = myPrevent.prefix();
final String redisKey = prefix + "_" + userId;
String s = stringRedisTemplate.opsForValue().get(redisKey);
if (!StringUtils.isEmpty(s)) {
Map<String, Object> result = new HashMap<>(2);
result.put("code", "500");
result.put("msg", "系统数据处理中...,请稍后");
return result;
}
stringRedisTemplate.opsForValue().set(redisKey, userId, myPrevent.expire(), myPrevent.timeUnit());
try {
return pjp.proceed();
} catch (Throwable throwable) {
throw new RuntimeException("系统异常");
}
}
}
控制器测试:
@RequestMapping("/myPrevent")
@RestController
public class MyPreventController {
@MyPrevent(prefix = "test", expire = 3, timeUnit = TimeUnit.SECONDS)
@RequestMapping("/test")
public Object test() {
return "test";
}
}