@Cacheable
含义:是Spring框架中自带的一个注解
作用:放在方法上时,是将这个方法返回的值,存入进redis中
存入规则:方法名+参数;也可以根据自己的项目需求,来对存入规则进行改写
改写示例:比如我们项目中就对存入规则进行了改写:
把方法的类名+方法名+参数名 作为缓存的key值
/**
* key的生成策略
* @return
*/
@Bean
@Override
public KeyGenerator keyGenerator() {
return [
generate:{ target, method, params->
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
if(!cachePrefix)
cachePrefix=""
return cachePrefix+sb.toString();
}
] as KeyGenerator
}
使用场景:
用于缓存,当项目需要对很多数据返回的首页列表,显示信息列表进行展示时,存入redis缓存中,可以大大提升加载速度
注意事项:
1.读取缓存时,会首先去redis中查找相同key值的记录,如果不存在就会另存一条在redis中;
如果存在就会取出返回
2.所以针对上条,我们要对缓存的数据进行更新修改时,需要将redis中的缓存清除,否则无法加载更新过后的内容
@CacheRemove
含义:一个注解用来清除redis缓存
作用:放在需要进行修改,删除等修改数据的接口方法上,对写有@Cacheable接口的缓存进行清除
代码示例:
1.注解
@Target([ElementType.METHOD, ElementType.TYPE ])
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface CacheRemove {
Class<?> cacheClass() default CacheRemove.class;//删除的类
String classFullPath() default ''//删除的类全路经
String[] method() default [];//删除的方法,可选
String key() default ''//删除的参数内容,可选
/**
* 删除条件,等于""则默认直接按键删除,否则condition为true才能删除
* #returnValue,代表的是返回值,其他标准spring el表达式
* returnValue是一个保留字,在使用缓存清除的方法上,方法参数名不能是returnValue,否则会出现无法访问参数的情况
* @return
*/
String condition() default "";
}
2.实现
/**
* 通过注解的方式去更新缓存
* @param point
*/
@AfterReturning(value = "@annotation(com.pkbigdata.annotation.CacheRemove)",returning = "returnValue")
public void afterReturning(JoinPoint point, def returnValue){
try {
def annotation = ((MethodSignature)point.getSignature()).getMethod().getAnnotation(com.pkbigdata.annotation.CacheRemove.class)
def paramName = getParams(((MethodSignature)point.getSignature()).getMethod()).each {
println(it.toString())
}
if (annotation.condition()&& (!annotation.condition().equals(""))){
def condition = el(annotation.condition(),returnValue,paramName,point.getArgs())
if (condition==false){//condition执行为真才继续清除,否则直接跳过
println("缓存condition为false,跳过")
return
}
}
def keys= [] as List
if(annotation.classFullPath()){
keys.add(annotation.classFullPath())
}
if(annotation.cacheClass()){
keys.add(annotation.cacheClass().getName())
}
keys.each {String key->
if (annotation.method().length==1){//单method
key+=annotation.method()[0]
if ("" != annotation.key()){
key+=annotation.key()
redisUtil.remove(cachePrefix+key)
}else {
redisUtil.removeByPrefix('*'+cachePrefix+key)
}
}else{
annotation.method().each {String method->
redisUtil.removeByPrefix('*'+cachePrefix+key+method)
}
}
println("清除的缓存key:"+cachePrefix+key)
}
}catch (Exception e){
println("清除的缓存异常")
e.printStackTrace()
}catch(Error e){
e.printStackTrace()
}
}
注意事项
清除键的方法一定要根据自己存入redis中的key值规则一样,否则无法清除 |