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