Spring @Cacheable @CacheRemove 笔记

论坛 期权论坛 脚本     
匿名技术用户   2021-1-2 06:50   11   0

@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值规则一样,否则无法清除

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP