@Slf4j
@Aspect
@Component
public class PushCacheInterceptor {
@Autowired
private BdrpProxy bdrpProxy;
@Around("@annotation(com.xxxx.PushCacheable)")
public Object handle(ProceedingJoinPoint jp) {
Object result = null;
MethodSignature signature = (MethodSignature) jp.getSignature();
Method method = signature.getMethod();
PushCacheable annotation = method.getAnnotation(PushCacheable.class);
if (annotation != null) {
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
String cacheKey = getCacheKey(jp, method);
log.info("get from redis cache key is {}", cacheKey);
long beginTime = System.currentTimeMillis();
String rets = null;
try {
rets = bdrpProxy.get(RedisClusterTypeEnum.STORAGE.getType(), cacheKey);
} catch (Throwable throwable) {
log.error("get bdrp is exception , cache key is {}", cacheKey);
}
long endTime = System.currentTimeMillis();
if (StringUtils.isNotBlank(rets)) {
log.info("hit cache , cache key is {}, cost: {}", cacheKey, (endTime - beginTime));
try {
result = jsonRedisSerializer.deserialize(rets.getBytes());
} catch (Exception e) {
log.warn("[cache] hit cache, but jsonRedisSerializer.deserialize fail");
result = null;
}
}
if (result != null) {
return result;
} else {
log.info("miss cache , load from db ,cache key is {}, cost: {}", cacheKey, (endTime - beginTime));
try {
result = jp.proceed();
} catch (Throwable throwable) {
log.error("{} invoke 1st fail,arguments is {}", jp.getTarget().getClass().getSimpleName() + "." +
method.getName(), Arrays.toString(jp.getArgs()));
}
if (result != null && StrUtil.isNotBlank(result.toString())) {
int expire = annotation.expire();
beginTime = System.currentTimeMillis();
byte[] redisValue = jsonRedisSerializer.serialize(result);
try {
if (redisValue != null) {
bdrpProxy.setEx(RedisClusterTypeEnum.STORAGE.getType(), cacheKey,
SafeEncoder.encode(redisValue), expire);
}
} catch (Throwable throwable) {
log.error("set bdrp is exception , cache key is {},", cacheKey, throwable);
}
endTime = System.currentTimeMillis();
log.info("set data to redis {}, cost: {}", result, (endTime - beginTime));
}
}
} else {
try {
result = jp.proceed();
} catch (Throwable throwable) {
log.error("{} invoke 2nd fail,arguments is {}", jp.getTarget().getClass().getSimpleName() + "." +
method.getName(), Arrays.toString(jp.getArgs()));
}
}
return result;
}
/**
* 获取缓存场景Redis Key
*/
String getCacheKey(ProceedingJoinPoint jp, Method method) {
return RedisConstants.CACHE_KEY_PREFIX + jp.getTarget().getClass().getSimpleName() + ":" + method.getName()
+ ":" + Joiner.on(":").join(jp.getArgs());
}
1、上方是声明缓存注解拦截
2、定义对应的注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface BcpPushCacheable {
/**
* 超时时间 默认600s
*/
int expire() default 600;
}
3、在需要缓存的方法上直接添加上注解即可