| | |
| | | |
| | | private static Pattern argPattern = Pattern.compile("\\$\\{arg([0-9])\\}"); |
| | | |
| | | //判断当前线程是否已经执行过目标方法的标志 |
| | | //判断当前线程是否已经执行过目标方法的标志 |
| | | private final ThreadLocal<Map<String, Object>> targetMethodResult = new ThreadLocal<Map<String, Object>>(); |
| | | |
| | | private Configuration cfg; |
| | | |
| | | /** 缓存 **/ |
| | | /** 缓存 **/ |
| | | @Autowired |
| | | ICacheService cache; |
| | | |
| | |
| | | |
| | | excuteMethodKey = this.getExecuteMethodKey(pjp); |
| | | |
| | | //读取缓存的注解 |
| | | //读取缓存的注解 |
| | | annoQCacheReader = AnnotationUtils.findAnnotation(methodSignature.getMethod(), QCacheReader.class); |
| | | //清理缓存注解 |
| | | //清理缓存注解 |
| | | annoQCacheCleaner = AnnotationUtils.findAnnotation(methodSignature.getMethod(), QCacheCleaner.class); |
| | | |
| | | if(annoQCacheReader!=null && annoQCacheCleaner==null){ |
| | |
| | | this.processReadCache(pjp, annoQCacheReader, methodSignature); |
| | | } |
| | | } catch (Exception e) { |
| | | logger.error("缓存处理失败,msg=" + e.getMessage(), e); |
| | | logger.error("缓存处理失败,msg=" + e.getMessage(), e); |
| | | } |
| | | |
| | | return clearAndReturnMethodResult(pjp,excuteMethodKey); |
| | |
| | | |
| | | strCacheKey = this.checkAndGenerateCacheKey(pjp.getTarget().getClass(), qCacheReader.cacheKey(), methodSignature, |
| | | converToParamMap(pjp.getArgs())); |
| | | //执行方法对应的key值 |
| | | //执行方法对应的key值 |
| | | String excuteMethodKey = this.getExecuteMethodKey(pjp); |
| | | |
| | | if (StringUtils.isNotEmpty(strCacheKey)) { |
| | |
| | | targetMethodResult.get().get(excuteMethodKey), expireTime); |
| | | } |
| | | }else{ |
| | | //如果result存在,则直接放入targetMethodResult中 |
| | | //如果result存在,则直接放入targetMethodResult中 |
| | | Map<String,Object> map = new HashMap<String,Object>(); |
| | | map.put(excuteMethodKey, result); |
| | | targetMethodResult.set(map); |
| | |
| | | executeTargetMethod(pjp,excuteMethodKey); |
| | | } |
| | | } catch (Throwable e) { |
| | | throw new Exception("添加缓存发生异常,strCacheKey=" + strCacheKey, e); |
| | | throw new Exception("添加缓存发生异常,strCacheKey=" + strCacheKey, e); |
| | | } |
| | | } |
| | | |
| | |
| | | for (int i = 0; i < strClearBucketArr.length; i++) { |
| | | strClearBucketArr[i] = CacheConstants.QXY_SERVICE_CACHE_NS.concat(strClearBucketArr[i]); |
| | | } |
| | | logger.info("清理的bucket:"+ArrayUtils.toString(strClearBucketArr)); |
| | | logger.info("清理的bucket:"+ArrayUtils.toString(strClearBucketArr)); |
| | | this.qCacheRedis.del(strClearBucketArr); |
| | | } |
| | | } catch (Throwable e) { |
| | | logger.error("清理缓存发生异常,strClearBucketArr" + ArrayUtils.toString(strClearBucketArr, ""), e); |
| | | logger.error("清理缓存发生异常,strClearBucketArr" + ArrayUtils.toString(strClearBucketArr, ""), e); |
| | | } |
| | | } |
| | | |
| | |
| | | String strNewKey = null; |
| | | |
| | | if (StringUtils.isNotEmpty(key)) { |
| | | logger.info("处理前的key:" + key); |
| | | logger.info("处理前的key:" + key); |
| | | |
| | | // 对部分参数进行替换处理 |
| | | // 对部分参数进行替换处理 |
| | | strNewKey = replaceArgInfo(key, paramMap); |
| | | // freeMarker解析cackeKey |
| | | // freeMarker解析cackeKey |
| | | strNewKey = parseCacheKey(strNewKey, targetClass, methodSignature, paramMap); |
| | | |
| | | logger.info("处理后的key:" + strNewKey); |
| | | logger.info("处理后的key:" + strNewKey); |
| | | if (strNewKey.length() > MAX_KEY_LENGTH) { |
| | | throw new Exception("Service缓存时Key过长,大于250个字符"); |
| | | throw new Exception("Service缓存时Key过长,大于250个字符"); |
| | | } |
| | | } |
| | | return strNewKey; |
| | |
| | | out.flush(); |
| | | return new String(stream.toByteArray(), "UTF-8"); |
| | | } catch (Exception e) { |
| | | logger.error("使用freemark解析cacheKey失败", e); |
| | | logger.error("使用freemark解析cacheKey失败", e); |
| | | throw e; |
| | | } finally { |
| | | IoUtils.closeQuietly(stream); |
| | |
| | | String strParamName = null; |
| | | Class<?> paramClz = null; |
| | | |
| | | logger.info("替换前的key:" + strCacheKey); |
| | | logger.info("替换前的key:" + strCacheKey); |
| | | if (StringUtils.isNotEmpty(strCacheKey) && paramMap != null && !paramMap.isEmpty()) { |
| | | matcher = argPattern.matcher(strCacheKey); |
| | | while (matcher.find()) { |
| | | strParamName = "arg" + matcher.group(1); |
| | | // 参数类型判断 |
| | | // 参数类型判断 |
| | | if (paramMap.containsKey(strParamName)) { |
| | | if(paramMap.get(strParamName)!=null){ |
| | | paramClz = paramMap.get(strParamName).getClass(); |
| | | if (paramClz.isAssignableFrom(java.lang.Object.class)) { |
| | | throw new Exception("错误:缓存参数类型不能是Object.class类型的对象"); |
| | | throw new Exception("错误:缓存参数类型不能是Object.class类型的对象"); |
| | | } else if (paramClz.isAssignableFrom(java.util.List.class) || paramClz.isArray()) { |
| | | matcher.appendReplacement(sbBuffer, "<#list " + strParamName + " as node>_${node}</#list>"); |
| | | } else if (paramClz.isAssignableFrom(java.util.Map.class)) { |
| | |
| | | } |
| | | } |
| | | } else { |
| | | throw new Exception("错误:参数表达式中存在不合法的参数"); |
| | | throw new Exception("错误:参数表达式中存在不合法的参数"); |
| | | } |
| | | } |
| | | matcher.appendTail(sbBuffer); |
| | | logger.info("替换后的key:" + sbBuffer.toString()); |
| | | logger.info("替换后的key:" + sbBuffer.toString()); |
| | | return sbBuffer.toString(); |
| | | }else{ |
| | | return strCacheKey; |
| | |
| | | } |
| | | |
| | | /** |
| | | * 执行目标方法,只允许执行一次,并保存当前结果 |
| | | * 执行目标方法,只允许执行一次,并保存当前结果 |
| | | * @param pjp |
| | | * @param key |
| | | * @throws Throwable |
| | |
| | | if(StringUtils.isEmpty(excuteMethodKey)){ |
| | | excuteMethodKey = this.getExecuteMethodKey(pjp); |
| | | } |
| | | //是否需要判断是否是void方法 |
| | | //是否需要判断是否是void方法 |
| | | if(targetMethodResult.get()==null || !targetMethodResult.get().containsKey(excuteMethodKey)){ |
| | | Map<String,Object> map = new HashMap<String,Object>(); |
| | | map.put(excuteMethodKey, pjp.proceed()); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 返回并清理ThreadLocal<Map<String, Object>>的MAP中的KEY |
| | | * 返回并清理ThreadLocal<Map<String, Object>>的MAP中的KEY |
| | | * @param pjp |
| | | * @param key |
| | | * @throws Throwable |
| | |
| | | if(StringUtils.isEmpty(excuteMethodKey)){ |
| | | excuteMethodKey = getExecuteMethodKey(pjp); |
| | | } |
| | | //是否需要判断是否是void方法(TODO) |
| | | //是否需要判断是否是void方法(TODO) |
| | | if(targetMethodResult.get()!=null && targetMethodResult.get().containsKey(excuteMethodKey)){ |
| | | result =targetMethodResult.get().get(excuteMethodKey); |
| | | targetMethodResult.get().remove(excuteMethodKey); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 返回当前目标方法的执行结果存储在ThreadLocal<Map<String, Object>>的MAP中的KEY |
| | | * 返回当前目标方法的执行结果存储在ThreadLocal<Map<String, Object>>的MAP中的KEY |
| | | * @param pjp |
| | | * @return key |
| | | */ |
| | |
| | | // } |
| | | // es.shutdown(); |
| | | // if(es.awaitTermination(1, java.util.concurrent.TimeUnit.HOURS)){ |
| | | // System.out.println("线程执行完成"); |
| | | // System.out.println("线程执行完成"); |
| | | // } |
| | | // long end = System.currentTimeMillis(); |
| | | // System.out.println(start-end); |