根据优化需要,数据查询的时候无法避免的使用Redis基于缓存查询,进而减少对于数据库的查询压力,对于过多的方法基于缓存存储,为提高代码的复用性,采用一种不过时的写法。
整体的逻辑是 根据key对应查询Redis 获取缓存信息,如果key值不存在,则对应字节在原方法中调用 直接进入数据库进行查询,通过jedis进行存入到Redis中。
描述注解的注解 就是元注解
此处可以理解为 自定义注解 进行对原注解的扩展
元注解:
自定义注解:
@Target(ElementType.METHOD) // 表示作用于方法
@Retention(RetenionPolicy.RUNTIME)// 表示运行时即效
public @interface CacheFind{
public String key() defalut "";
public String seconds() defalut 0;
}
此时对应于 注解CacheFind 就可以应用于对应的方法上,只不过目前还未做对应的方法实现功能。对应结合AOP 声明对应的切面,进行功能逻辑的扩展。

@Around
Bean 用于指定bean对象的所有方法
Within 用于匹配指定包下所有的类
Execution用于按照指定语法规则匹配到具体的方法
Annotation 用于指定注解修饰的方法
对应的切面
使用自定义注解,实现Redis的查询扩充
@Aspect
@Component
public calss RedisAop{
Private static final ObjectMapper mapper = new ObjectMapper();
@Autowired
private Jedis jedis;
@Around("@annotation(cachefind)")
public Object around(ProceedingJoinPoint joinPoint,CacheFind cachefind){
String key =getKey(joinPoint,cacheFind);
String json=jedis.get(key);
Object returnObject=null;
if(StringUtils.isEmpty(json)){
// 如果此处数据 不存在于Redis缓存中 则直接执行原方法 直接进行数据库的查询
try{
returnObject=joinPoint.proceed();
String objJSON=mapper.writeValueAsString(returnObject);
// 对应reids中的超时时间 判断是否指定还是默认
if(cacheFind.seconds>0){
jedis.setex(key,chacheFind.seconds,objJSON);
}else{
jedis.set(key,objJSON);
}
}catch(Throwable e){
e.printStackTrace();
throw new RuntimeException();
}
}else{
// 获取返回对象的字节码
Class<?> targetClass=getClass(joinPoint);
// 此处的转换需要 进行将json转换为java 然后返回
returnObject=mapper.readValue(json,targetClass);
}
return returnObject
}
private String getKey(ProceedingJoinPoint joinPoint,CacheFind cachefind){
if(!StringUtils.isEmpty(cacheFind.key())){
return cacheFind.key();
}
String className = joinPoint.getSignature().getDeclaringTypeName();
String methodName= joinPoint.getStignature().getName();
String firstArg= joinPoint.getArgs()[0].toString();
return className+methodName+"::"+firstArgs;
}
private Class<?> getClass(ProceedingJoinPoint joinPoint){
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
return methodSignature.getReturenType();
}
}