/**
 *  方法缓存注解
 * 
 * 
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodCache {
  /**
   * redisKey 的一部分 最终的 rediskey是 appId + subAppId + key + (方法对应的参数)
   * 
   */
   String key();

   /**
    *  缓存时间 单位为秒
    */
    int expireTime() default 3600;
}

@Sl4j
@Aspect
@Component
public class MethodCacheAspect {
     @Resource
     private RedisTemplate<String, String> redisTemplate;

     @Value("${application.appId}")
     private String appId;
     
     @Value("${application.subAppId}")
     private String subAppId;

     @Pointcut(value = "@annotation(com.fengye.it.utils.annotations.MethodCache)")
     public Object doAround(ProceedingJoinPointjoinPoint, MethodCache methodCache) throws Throwable {
         log.info("MethodCacheAspect doAround start==>);
         // 构造KEY appId + subAppId + key + (方法对应的参数)
         StringBuilder sb = new StringBuilder(appId);
         sb.append(subAppId).append(methodCache.key());
         Object[] args = joinPoint.getArgs();
         if (args != null && args.length !=0) {
            for (Object arg : args) {
                sb.append(arg.toString());
            }
         }
         String redisKey = sb.toString();
         log.info("MethodCacheAspect doAround redisKey==>:{}", redisKey);

         // 获取缓存 没有则新增
         String value = redisTemplate.opsForValue().get(redisKey);
         if (value == null) {
             // 没有缓存 则执行方法
             Object proceed = joinPoint.proceed();
             String jsonString = JSONObject.toJSONString(proceed, SerializerFeature.WriteMapNullValue);
             // 并保存到redis
             redisTemplate.opsForValue().set(redisKey, jsonString, methodCache.expireTime(), TimeUnit.SECONDS);
             return proceed;
         }
         // 获取目标方法对应返回值的class对象
         Signature signature = joinPoint.getSignature();
         if (signature instanceof MethodSignature) {
             Class returnType = ((MethodSignature) signature).getReturnType();
             return JSONObject.parseObject(value).toJavaObject(returnType);
         }
         log.error("MethodCacheAspect doAround signature is not MethodSignature redisKey==>:{}", redisKey);
         return joinPoint.proceed();
     }
}        

  

posted on 2024-06-17 23:15  人无名,则可专心练剑  阅读(1)  评论(0编辑  收藏  举报