//切面 = 切入点 + 通知
@Aspect //标识切面
@Component //交给spring容器管理
public class CacheAspect {
@Autowired(required = false)
private JedisCluster jedis; //注入redis集群对象
/**
* 利用AOP规则:动态获取注解对象
* 步骤:
* 1.根据key查询redis.
* 2.没有数据,需要让目标方法执行.查询的结果保存redis
* 3.将json串转化为返回值对象 返回.
* @param joinPoint
* @param cacheFind
* @return
*/
@Around("@annotation(cacheFind)")
public Object around(ProceedingJoinPoint joinPoint, Cache_Find cacheFind) {
//cacheFind必须和@Around("@annotation(cacheFind)")中的cacheFind保持一致
Object data = null;
String key = getKey(joinPoint,cacheFind);
//1.从redis中获取数据
String result = jedis.get(key);
//2.判断缓存中是否有数据
try {
if(StringUtils.isEmpty(result)) {
//2.1缓存中没有数据
data = joinPoint.proceed();//目标方法执行,即添加了@Cache_Find注解的方法执行,查询数据库
//2.2将返回值结果,转化为jsonStr
String json = ObjectMapperUtil.toJSON(data);
//2.3判断用户是否编辑时间
//如果有时间,必须设定超时时间.
if(cacheFind.seconds()>0) {
int seconds = cacheFind.seconds();
jedis.setex(key,seconds, json);//有超时时间的方法
}else {
jedis.set(key,json);//没有超时时间的方法
}
System.out.println("AOP查询数据库!!!!!");
}else {
//表示缓存数据不为空,将缓存数据转化为对象
Class returnClass = getReturnClass(joinPoint);
data = ObjectMapperUtil.toObject(result,returnClass);
System.out.println("AOP查询缓存!!!!");
}
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e);//全局处理了RuntimeException
}
return data;
}
/**
* 获取目标方法的返回值类型,即添加了@Cache_Find注解的方法的返回值类型
* @param joinPoint
* @return
*/
private Class getReturnClass(ProceedingJoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
return signature.getReturnType();
}
/**
* 动态获取key
* @param joinPoint
* @param cacheFind
* @return
*/
private String getKey(ProceedingJoinPoint joinPoint, Cache_Find cacheFind) {
String key = cacheFind.key(); //如果使用@Cache_Find注解时,给了key值,使用给的key值
if(StringUtils.isEmpty(key)) { //如果使用@Cache_Find注解时,没有给key值,则自动生成一个key值
//获取添加了@Cache_Find注解的方法所在的全类名
String className = joinPoint.getSignature().getDeclaringTypeName();
//获取添加了@Cache_Find注解的方法名
String methodName = joinPoint.getSignature().getName();
if(joinPoint.getArgs().length>0)
//joinPoint.getArgs()[0] 是获取添加了@Cache_Find注解的方法的第一个参数
key = className+"."+methodName+"::" + joinPoint.getArgs()[0];
else
key = className+"."+methodName;
}
return key;
}
}