/** * 方法缓存注解 * * */ @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(); } }