|
|
|
@@ -56,90 +56,91 @@ public class RedisCacheAspect { |
|
|
|
|
|
|
|
@Around("cacheAspect()") |
|
|
|
public Object round(ProceedingJoinPoint jp) throws Throwable { |
|
|
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); |
|
|
|
// 查询token信息 |
|
|
|
//从header中获取token |
|
|
|
String token = request.getHeader("token"); |
|
|
|
//如果header中不存在token,则从参数中获取token |
|
|
|
if (StringUtils.isBlank(token)) { |
|
|
|
token = request.getParameter("token"); |
|
|
|
} |
|
|
|
log.info("token>>>>>>>>>>>>>>>"+token); |
|
|
|
String tenantId; |
|
|
|
WxCUser wxCUser = null ; |
|
|
|
if(StringUtils.isNotBlank(token)) { |
|
|
|
wxCUser = userTokenService.getByToken(token); |
|
|
|
} |
|
|
|
if (Objects.isNull(wxCUser) || wxCUser.getExpireTime().getTime() < System.currentTimeMillis()) { |
|
|
|
tenantId = "0"; |
|
|
|
} else { |
|
|
|
tenantId = wxCUser.getTenantId(); |
|
|
|
} |
|
|
|
|
|
|
|
// 请求参数 |
|
|
|
Object[] args = jp.getArgs(); |
|
|
|
// 接口 返回结果 |
|
|
|
Object result; |
|
|
|
String redisKey; |
|
|
|
|
|
|
|
//得到注释的名称 |
|
|
|
MethodSignature signature = (MethodSignature) jp.getSignature(); |
|
|
|
//判断tag是否在用户权限中 如果存在加入参数查询 |
|
|
|
Method method = signature.getMethod(); |
|
|
|
RedisCache cache = method.getAnnotation(RedisCache.class) ; |
|
|
|
if (cache.autoKey()) { |
|
|
|
// 构建 redisKey => reqPath:tenantId:md5(param1_param2_param3) |
|
|
|
String requestUrl = request.getRequestURI(); |
|
|
|
// 接口路径 reqPath => /api/xxx |
|
|
|
String reqPath = requestUrl.substring(requestUrl.indexOf("/api/")); |
|
|
|
if (cache.md5()) { |
|
|
|
String md5Before = StringUtils.join(args, DELIMITER_PARAMS); |
|
|
|
redisKey = StringUtils.join(reqPath, DELIMITER_KEY, tenantId, DELIMITER_KEY, HashUtil.md5(StringUtils.join(token, md5Before, DELIMITER_PARAMS))); |
|
|
|
} else { |
|
|
|
redisKey = StringUtils.join(reqPath, DELIMITER_KEY, tenantId, DELIMITER_KEY, StringUtils.join(token,args, DELIMITER_PARAMS)); |
|
|
|
} |
|
|
|
} else { |
|
|
|
redisKey = cache.key(); |
|
|
|
} |
|
|
|
|
|
|
|
// redisKey 不存在,获取接口数据并返回 |
|
|
|
if (StringUtils.isBlank(redisKey)) { |
|
|
|
result = jp.proceed(args); |
|
|
|
} else { |
|
|
|
ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue(); |
|
|
|
String value = valueOperations.get(redisKey); |
|
|
|
if (value == null) { |
|
|
|
String lockKey = StringUtils.join(redisKey, ":", "lock"); |
|
|
|
long time = System.currentTimeMillis() + 2000; |
|
|
|
String timeStr = String.valueOf(time); |
|
|
|
try { |
|
|
|
//分布式锁,保证一个线程读DB,其它线程排队 |
|
|
|
if (redisLock.lock2(lockKey, timeStr)) { |
|
|
|
log.debug("CacheAspect 读库中, key:{}: " + lockKey); |
|
|
|
result = jp.proceed(args); |
|
|
|
String json_data = JSONObject.toJSONString(result); |
|
|
|
valueOperations.set(redisKey, json_data, cache.expireTime(), cache.dateUnit()); |
|
|
|
log.debug("CacheAspect 缓存不存在,获取接口数据并放入缓存,key:{}, expire:{}", redisKey, cache.expireTime()); |
|
|
|
} else { |
|
|
|
log.debug("CacheAspect 读库等待中, key:{}: " + lockKey); |
|
|
|
Thread.sleep(2000); |
|
|
|
value = valueOperations.get(redisKey); |
|
|
|
result = parseCache(jp, redisKey, value); |
|
|
|
} |
|
|
|
} catch (Throwable throwable) { |
|
|
|
log.error("CacheAspect proceed error , Illegal argument: {} in {}.{}()", Arrays.toString(jp.getArgs()), |
|
|
|
jp.getSignature().getDeclaringTypeName(), jp.getSignature().getName(), throwable); |
|
|
|
throw throwable; |
|
|
|
} finally { |
|
|
|
redisLock.unlock(lockKey, timeStr); |
|
|
|
} |
|
|
|
} else { |
|
|
|
result = parseCache(jp, redisKey, value); |
|
|
|
} |
|
|
|
// 计数器 |
|
|
|
stringRedisTemplate.opsForHash().increment("hotapi", redisKey, 1); |
|
|
|
} |
|
|
|
return result; |
|
|
|
// HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); |
|
|
|
// // 查询token信息 |
|
|
|
// //从header中获取token |
|
|
|
// String token = request.getHeader("token"); |
|
|
|
// //如果header中不存在token,则从参数中获取token |
|
|
|
// if (StringUtils.isBlank(token)) { |
|
|
|
// token = request.getParameter("token"); |
|
|
|
// } |
|
|
|
// log.info("token>>>>>>>>>>>>>>>"+token); |
|
|
|
// String tenantId; |
|
|
|
// WxCUser wxCUser = null ; |
|
|
|
// if(StringUtils.isNotBlank(token)) { |
|
|
|
// wxCUser = userTokenService.getByToken(token); |
|
|
|
// } |
|
|
|
// if (Objects.isNull(wxCUser) || wxCUser.getExpireTime().getTime() < System.currentTimeMillis()) { |
|
|
|
// tenantId = "0"; |
|
|
|
// } else { |
|
|
|
// tenantId = wxCUser.getTenantId(); |
|
|
|
// } |
|
|
|
// |
|
|
|
// // 请求参数 |
|
|
|
// Object[] args = jp.getArgs(); |
|
|
|
// // 接口 返回结果 |
|
|
|
// Object result; |
|
|
|
// String redisKey; |
|
|
|
// |
|
|
|
// //得到注释的名称 |
|
|
|
// MethodSignature signature = (MethodSignature) jp.getSignature(); |
|
|
|
// //判断tag是否在用户权限中 如果存在加入参数查询 |
|
|
|
// Method method = signature.getMethod(); |
|
|
|
// RedisCache cache = method.getAnnotation(RedisCache.class) ; |
|
|
|
// if (cache.autoKey()) { |
|
|
|
// // 构建 redisKey => reqPath:tenantId:md5(param1_param2_param3) |
|
|
|
// String requestUrl = request.getRequestURI(); |
|
|
|
// // 接口路径 reqPath => /api/xxx |
|
|
|
// String reqPath = requestUrl.substring(requestUrl.indexOf("/api/")); |
|
|
|
// if (cache.md5()) { |
|
|
|
// String md5Before = StringUtils.join(args, DELIMITER_PARAMS); |
|
|
|
// redisKey = StringUtils.join(reqPath, DELIMITER_KEY, tenantId, DELIMITER_KEY, HashUtil.md5(StringUtils.join(token, md5Before, DELIMITER_PARAMS))); |
|
|
|
// } else { |
|
|
|
// redisKey = StringUtils.join(reqPath, DELIMITER_KEY, tenantId, DELIMITER_KEY, StringUtils.join(token,args, DELIMITER_PARAMS)); |
|
|
|
// } |
|
|
|
// } else { |
|
|
|
// redisKey = cache.key(); |
|
|
|
// } |
|
|
|
// |
|
|
|
// // redisKey 不存在,获取接口数据并返回 |
|
|
|
// if (StringUtils.isBlank(redisKey)) { |
|
|
|
// result = jp.proceed(args); |
|
|
|
// } else { |
|
|
|
// ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue(); |
|
|
|
// String value = valueOperations.get(redisKey); |
|
|
|
// if (value == null) { |
|
|
|
// String lockKey = StringUtils.join(redisKey, ":", "lock"); |
|
|
|
// long time = System.currentTimeMillis() + 2000; |
|
|
|
// String timeStr = String.valueOf(time); |
|
|
|
// try { |
|
|
|
// //分布式锁,保证一个线程读DB,其它线程排队 |
|
|
|
// if (redisLock.lock2(lockKey, timeStr)) { |
|
|
|
// log.debug("CacheAspect 读库中, key:{}: " + lockKey); |
|
|
|
// result = jp.proceed(args); |
|
|
|
// String json_data = JSONObject.toJSONString(result); |
|
|
|
// valueOperations.set(redisKey, json_data, cache.expireTime(), cache.dateUnit()); |
|
|
|
// log.debug("CacheAspect 缓存不存在,获取接口数据并放入缓存,key:{}, expire:{}", redisKey, cache.expireTime()); |
|
|
|
// } else { |
|
|
|
// log.debug("CacheAspect 读库等待中, key:{}: " + lockKey); |
|
|
|
// Thread.sleep(2000); |
|
|
|
// value = valueOperations.get(redisKey); |
|
|
|
// result = parseCache(jp, redisKey, value); |
|
|
|
// } |
|
|
|
// } catch (Throwable throwable) { |
|
|
|
// log.error("CacheAspect proceed error , Illegal argument: {} in {}.{}()", Arrays.toString(jp.getArgs()), |
|
|
|
// jp.getSignature().getDeclaringTypeName(), jp.getSignature().getName(), throwable); |
|
|
|
// throw throwable; |
|
|
|
// } finally { |
|
|
|
// redisLock.unlock(lockKey, timeStr); |
|
|
|
// } |
|
|
|
// } else { |
|
|
|
// result = parseCache(jp, redisKey, value); |
|
|
|
// } |
|
|
|
// // 计数器 |
|
|
|
// stringRedisTemplate.opsForHash().increment("hotapi", redisKey, 1); |
|
|
|
// } |
|
|
|
// return result; |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
private Object parseCache(ProceedingJoinPoint jp, String redisKey, String value) { |
|
|
|
|