定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SliceRuleCache {
public String cacheKey() default "";
public long expireTime() default 0L;
public String cachePreFix() default "slice";
}
解析注解
@Aspect
@Component
@Slf4j
public class SliceRuleCacheAspect {
@Autowired
private RedisHelper redisHelper;
@Autowired
private InnerAlarmService innerAlarmService;
@Pointcut("execution(public * com.ksyun.billing.rule.service.*.*(..))")
public void serviceAspectPointCut() {
}
@Pointcut("execution(public * com.ksyun.billing.rule.service.remote.*.*(..))")
public void remoteServiceAspectPointCut() {
}
@Pointcut("serviceAspectPointCut() || remoteServiceAspectPointCut()")
public void cacheAroundAspectPointCut() {
}
@Around("cacheAroundAspectPointCut()")
public Object cacheAroundAspect(ProceedingJoinPoint joinPoint) throws Throwable {
Object proceedResult = null;
Object targetClass = joinPoint.getTarget();
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Object[] joinPointArgs = joinPoint.getArgs();
String signatureName = methodSignature.getName();
Class[] parameterTypes = methodSignature.getParameterTypes();
log.info("signatureName:{},parameterTypes:{}", signatureName, parameterTypes);
try {
Method targetMethod = targetClass.getClass().getMethod(signatureName, parameterTypes);
log.info("targetMethod:{}", targetMethod);
SliceRuleCache targetCacheAnnotation = targetMethod.getAnnotation(SliceRuleCache.class);
if (targetCacheAnnotation == null) {
proceedResult = joinPoint.proceed();
return proceedResult;
}
long expireTime = targetCacheAnnotation.expireTime();
String cacheKey = getCacheKey(targetCacheAnnotation.cacheKey(), targetCacheAnnotation.cachePreFix(),
methodSignature,
joinPointArgs);
log.info("build cacheKey:{}", cacheKey);
String cacheResult = "";
try {
Optional<String> cacheOp = redisHelper.get(cacheKey);
if (cacheOp.isPresent()) {
cacheResult = cacheOp.get();
}
} catch (Exception ex) {
log.error("get cache from redis occur error,cacheKey:{}", cacheKey, ex);
innerAlarmService.innerAsyAlarmOnlyOnePiece(AlarmGroupNameEnum.INNER_EXCEPTION.getBizName(),
ex.getMessage());
}
if (StringUtils.isNotBlank(cacheResult)) {
log.info("cache is exist,get result form cache,key:{}", cacheKey);
Class targetReturnClass = targetMethod.getReturnType();
if (methodSignature.getReturnType() == List.class) {
if (targetMethod.getGenericReturnType() instanceof ParameterizedType) {
Type[] actualTypeArguments =
((ParameterizedType) targetMethod.getGenericReturnType()).getActualTypeArguments();
targetReturnClass = Class.forName(actualTypeArguments[0].getTypeName());
}
proceedResult = JSON.parseArray(cacheResult, targetReturnClass);
} else {
proceedResult = JSON.parseObject(cacheResult, targetReturnClass);
}
} else {
proceedResult = joinPoint.proceed();
log.info("cache is not exist,get result form targetMethod:{}", targetMethod);
if (proceedResult != null) {
redisHelper.setex(cacheKey, Jackson.toJsonString(proceedResult),
Integer.valueOf(String.valueOf(expireTime)));
}
}
return proceedResult;
} catch (Exception ex) {
log.error("cacheAroundAspect occur error", ex);
throw ex;
}
}
private String getCacheKey(String cacheKey, String cachePreFix, MethodSignature methodSignature,
Object[] joinPointArgs) {
StringBuilder stringBuilder = new StringBuilder("");
if (StringUtils.isNotBlank(cachePreFix)) {
stringBuilder.append(cachePreFix).append("_");
}
String methodSignatureName = methodSignature.getName();
stringBuilder.append(methodSignatureName);
if (StringUtils.isNotBlank(cacheKey)) {
stringBuilder.append("_").append(cacheKey);
return stringBuilder.toString();
}
if (joinPointArgs != null && joinPointArgs.length > 0) {
for (Object obj : joinPointArgs) {
stringBuilder.append("_").append(obj);
}
}
return stringBuilder.toString();
}
}