缓存基于redis
@Target(ElementType.METHOD,ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface RepeatSubmit {
/**
* 需要忽略的参数
* @return
*/
String[] ignoreParam() default {};
/**
*
* @return
*/
String returnObj() default "";
/**
* 单位时间默认3秒
* @return
*/
long unitTime() default 3L;
/**
* 是否限制为同一ip
* @return
*/
boolean limitIp() default false;
}
@Aspect
@Component
@Slf4j
public class RepeatSubmitAspect {
@Autowired
private RedisClient redisClient;
@Pointcut("@annotation(com.*类全路径*.RepeatSubmit)||@within(com.*类全路径*.RepeatSubmit)")
public void cut() {
}
@Around("cut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
RepeatSubmit repeatSubmit = getAnnotation(proceedingJoinPoint);
Object o = proceedingJoinPoint.proceed();
if(Objects.isNull(repeatSubmit)){
log.info("【repeatsubmit】缓存失败获取不到缓存目标annotation");
return o;
}
String[] ignoreArr = repeatSubmit.ignoreParam();
List ignoreList = CollectionUtils.arrayToList(ignoreArr);
String returnObj = repeatSubmit.returnObj();
StringBuilder key = new StringBuilder("repeatCheck-");
//类名
String className = proceedingJoinPoint.getSignature().getDeclaringTypeName();
//方法名称
String methodName = proceedingJoinPoint.getSignature().getName();
key.append(className);
key.append(methodName);
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(Objects.isNull(attributes)){
log.info("【repeatsubmit】缓存失败获取不到缓存目标attributes");
return o;
}
HttpServletRequest request = attributes.getRequest();
Map<String, String[]> map = request.getParameterMap();
//方法参数
map.forEach((k,v) -> {
if(!ignoreList.contains(k)){
for (String s : v) {
key.append(s);
}
}
});
if(repeatSubmit.limitIp()){
key.append(request.getRemoteHost());
}
long unitTime = repeatSubmit.unitTime();
//检查是否为重复提交
Object result = redisClient.get(key.toString());
if(Objects.isNull(result)){
if(!StringUtils.hasText(returnObj)){
redisClient.set(key.toString(), BaseResult.success(),unitTime);
}else{
redisClient.set(key.toString(), returnObj,unitTime);
}
redisClient.set(key.toString(), o ,unitTime);
return o;
}else{
log.info("【repeatsubmit】从缓存中获取返回数据:{}",result);
return result;
}
}
/**
* 获得注解
* @param joinPoint
* @return
* @throws Exception
*/
private static RepeatSubmit getAnnotation(JoinPoint joinPoint){
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null) {
return method.getAnnotation(RepeatSubmit.class);
}
return null;
}
说明:单位时间内(unitTime)参数一样的重复请求会直接从redis中读取上次的缓存结果返回
版权声明:本文为bobjy_happybird原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。