SpringBoot缓存相关的注解使用

  • A+

Spring框架提供了便捷的缓存操作。不会对业务调用造成任何干扰,类似于@Transactional支持。不需要手动存取,删除缓存,只需要在类或者方法上进行少量的注解就可以自动完成这些操作。本篇主要介绍了SpringBoot缓存相关的注解使用,要了解基本原理的点击跳转:SpringBoot缓存原理

一.概念

1.主要注解

  • 注解总览
    1. @EnableCaching: 开启spring cache功能
    2. @Cacheable:添加缓存
    3. @CacheEvict:删除缓存
    4. @CachePut:更新缓存,方法依旧执行,通常用于更新方法
    5. @Caching:在一个方法中同时使用多个缓存规则
    6. @CacheConfig:在类级别上设置一些通用的属性

2.@Cacheable/@CachePut/@CacheEvict 主要的参数

  • value: 缓存的key值,必须指定至少一个,可指定多个 ,指定多个将依次查询缓存直到命中 。
    例如:@Cacheable(value=”cache”) 或者@Cacheable(value={”cache1”,”cache2”})
  • key: 缓存的key值,可为空,若为空按照KeyGenerator的生成规则来。支持 SpEL 表达式。
    例如:@Cacheable(value=”cache”,key=”#id”)
  • condition:指定缓存条件,可以为空,支持 SpEL ,返回 true 或者 false,只有为 true 才进行缓存/清除缓存。
    例如:@Cacheable(value=”cache”,condition=”#name.length()>2”)
  • unless:否定缓存。当条件结果为TRUE时,就不会缓存。
    例如:@Cacheable(value=”cache”,unless=”#name.length()>2”)
  • allEntries(@CacheEvict ) 是否清空value定义的所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存
    例如:@CachEvict(value=”testcache”,allEntries=true)
  • beforeInvocation(@CacheEvict) 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存
    例如:@CachEvict(value=”cache”,beforeInvocation=true)

3.SpEL上下文数据

  • Spring Cache提供了一些供我们使用的SpEL上下文数据,如下:
    名称 位置 描述 范例
    methodName Root对象 当前被调用的方法名 #root.methodName
    method Root对象 当前被调用的方法 #root.method.name
    target Root对象 当前被调用的目标对象实例 #root.target
    targetClass Root对象 当前被调用的目标对象的类 #root.targetClass
    args Root对象 当前被调用的方法的参数列表 #root.args[0]
    caches Root对象 当前方法调用使用的缓存列表 #root.caches[0].name
    Argument name 执行上下文 适用任何方法的参数 #iban(iban为参数名) 或者 #a<#arg> 或者#p<#arg> (arg代表参数索引,从0开始)
    result 执行上下文 方法返回值,在unless,cachePut,cacheEvict(beforeInvocation为false)时使用 #result 受支持的包装器(如Optional)#result是指实际对象
  • 注意
    1. 当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。 如
      @Cacheable(key = "targetClass + methodName +#p0")
    2. 使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。 如:@Cacheable(value="cache", key="#id")
      @Cacheable(value="cache", key="#p0")

4.SpEL运算符

  • 运算符:
    类型 运算符
    关系 <,>,<=,>=,==,!=,lt,gt,le,ge,eq,ne
    算术 +,- ,* ,/,%,^
    逻辑 &&,||,!,and,or,not,between,instanceof
    条件 ?: (ternary),?: (elvis)
    正则表达式 matches
    其他类型 ?.,?[…],![…],^[…],$[…]

二.使用

1.引入缓存

  • spring-boot中引入缓存
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-cache</artifactId>
            </dependency>
        </dependencies>
    

2.使用@EnableCaching启动缓存

  • 启用缓存
    @EnableCaching
    @SpringBootApplication
    public class SpringBootCacheAnnotationApplication {
        public static void main(String[] args) {
            SpringApplication.run(SpringBootCacheAnnotationApplication.class, args);
        }
    }
    

3.定义打印内存中的所有缓存的方法

  • 返回缓存
    @Component
    @RestController
    public class CacheInfo {
        //将所有缓存封装到RModel对象中
        @Autowired
        ApplicationContext applicationContext;
        public  Map<String,Map<String,String>> cache(){
            Map<String,Map<String,String>>   rCache= new HashMap<>();
            ConcurrentMapCacheManager bean = applicationContext.getBean(ConcurrentMapCacheManager.class);//获取内存管理器(cacheManager)
            Collection<String> cacheNames = bean.getCacheNames();//获取指定key内存
            cacheNames.stream().forEach(x->{
                rCache.put(x,new HashMap<>());
                ConcurrentMapCache cache    = (ConcurrentMapCache)bean.getCache(x);//获取指定cache
                cache.getNativeCache().forEach((y,z)-> rCache.get(x).put(y.toString(),z.toString()));//获取map中的key和value
            });
            return rCache;
        }
    
        @GetMapping("/cacheInfo")
        public Map<String,Map<String,String>> getCacheInfo(){
            return  cache();
        }
    }
    
  • 访问localhost:8080/cacheInfo,就可以获取到所有的缓存

4.@Cacheable使用

  1. 检查方法返回结果是否被缓存,若无缓存,执行方法后缓存
    //使用默认值
    @Cacheable("cacheableSpace")
    public BusinessModel cacheableMethod(BusinessModel businessModel) {
        return  businessModel;
    }
    
    //使用固定值
    @Cacheable(value = "cacheableSpace" ,key = "'fixKey'")
    public BusinessModel CacheableMethodFix(BusinessModel businessModel) {
        return businessModel;
    }
    
    //使用SpEL
    @Cacheable(value = "cacheableSpace" ,key = "'target:'+target+'-methodName:'+methodName+'-targetClass:'+targetClass+'-method:'+method+'-args:'+#businessModel")
    public BusinessModel CacheableMethodSpEL(BusinessModel businessModel) {
        return businessModel;
    }
    
    @Cacheable(value = "cacheableSpace" ,key = "#p0+#p1+#sex+#a3")
    public BusinessModel CacheableMethodSpEL2(String  name, Integer age, Boolean sex, Timestamp date) {
        return new BusinessModel(name,age, sex,date);
    }
    
  2. 在缓存中的数据存储形式
    {
        "cacheableSpace": {
            "target:org.friends.springbootcacheannotation.cacheable.BusinessService@3975ec13-methodName:CacheableMethodSpEL-targetClass:class org.friends.springbootcacheannotation.cacheable.BusinessService-method:public org.friends.springbootcacheannotation.BusinessModel org.friends.springbootcacheannotation.cacheable.BusinessService.CacheableMethodSpEL(org.friends.springbootcacheannotation.BusinessModel)-args:BusinessModel(name=Joey, age=22, sex=true, date=2019-04-05 12:00:00.0)": "BusinessModel(name=Joey, age=22, sex=true, date=2019-04-05 12:00:00.0)",
            "fixKey": "BusinessModel(name=Joey, age=22, sex=true, date=2019-04-05 12:00:00.0)",
            "Joey22true2019-04-05 12:00:00.0": "BusinessModel(name=Joey, age=22, sex=true, date=2019-04-05 12:00:00.0)",
            "BusinessModel(name=Joey, age=22, sex=true, date=2019-04-05 12:00:00.0)": "BusinessModel(name=Joey, age=22, sex=true, date=2019-04-05 12:00:00.0)",
        }
    }
    
  3. 所有属性概览
    String[] value() default {}; //存储的空间key
    String key() default ""; //数据缓存key
    String[] cacheNames() default {}; //和value注解差不多,二选一
    String keyGenerator() default ""; //key的生成器。key/keyGenerator二选一使用
    String cacheManager() default ""; //指定缓存管理器
    String cacheResolver() default ""; //或者指定获取解析器
    String condition() default ""; //条件符合则缓存
    String unless() default ""; //条件符合则不缓存
    boolean sync() default false; //是否使用异步模式
    
  4. 注意:①注解上定义了key将不在使用默认的生成规则 ②value是必须存在的值,标识存储空间名

5.@CacheConfig的使用

  1. 在类上可以使用@CacheConfig(cacheNames = {"myCache"})注解来统一指定value的值,这时可省略value,如果方法上依旧写了value,以方法的value值为准;这个注解可以放在类,接口或者注解上
    @Service
    @CacheConfig(cacheNames = {"myCahce"})
    public class CacheConfigBusinessService {
        @Cacheable(key = "targetClass + methodName +#p0")//此处不需value
        public String[] CacheconfigMethod(String ids) {
            return StringUtils.split(ids, ",");
        }
    }
    
  2. 所有属性概览
    String[] cacheNames() default {}; //定义存储空间
    String keyGenerator() default "";  //key的生成器。key/keyGenerator二选一使用
    String cacheManager() default "";  //指定缓存管理器
    String cacheResolver() default ""; //或者指定获取解析器
    

6.@CachePut的使用

  1. @CachePut注解,每次执行都会触发方法的执行,从而更新缓存;常用于update方法和更新一些共用缓存
    @CachePut(value = "updateCache", key = "targetClass+ methodName +#p0")
    public BusinessModel updateMethod(BusinessModel businessModel) {
        return businessModel;
    }
    
  2. 所有属性概览
    String[] value() default {}; //存储的空间key
    String key() default ""; //数据缓存key
    String[] cacheNames() default {}; //和value注解差不多,二选一
    String keyGenerator() default ""; //key的生成器。key/keyGenerator二选一使用
    String cacheManager() default ""; //指定缓存管理器
    String cacheResolver() default ""; //或者指定获取解析器
    String condition() default ""; //条件符合则缓存
    String unless() default ""; //条件符合则不缓存
    

7.@CacheEvict的使用

  1. @CacheEvict注解,其中比较重要的注解有①allEntries默认false,若为true则删除定义空间内的所有缓存 ②beforeInvocation 若为true,在方法执行前删除缓存
      //存储缓存
        @Cacheable(value = "temp",key = "#p0.name")
        public BusinessModel save(BusinessModel businessModel) {
            return businessModel;
        }
    
        //删除指定name的缓存
        @CacheEvict(value="temp",key="#name")
        public void delete(String name) {
            //delete  name define cache
        }
    
        //方法调用后清除定义空间内的缓存
        @CacheEvict(value="temp",allEntries=true)
        public void deleteAll() {
         //delete all
        }
    
        //方法调用前清除清除定义空间内的缓存
        @CacheEvict(value="temp",allEntries=true,beforeInvocation=true)
        public void deleteAllBefore() {
           //delete all
        }
    
  2. 所有属性概览
    String[] value() default {}; //存储的空间key
    String key() default ""; //数据缓存key
    String[] cacheNames() default {}; //和value注解差不多,二选一
    String keyGenerator() default ""; //key的生成器。key/keyGenerator二选一使用
    String cacheManager() default ""; //指定缓存管理器
    String cacheResolver() default ""; //或者指定获取解析器
    String condition() default ""; //条件符合则删除缓存
    boolean allEntries() default false;//清除本存储空间内的所有缓存
    boolean beforeInvocation() default false;//是否在方法执行前清除
    

8.@Caching使用

  1. @Caching可以组合多个注解,可以通过此注解整合多个功能也可以自定义注解使用
    @Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") })
    public Book importBooks(String deposit, Date date){}
    
  2. 所有属性概览
         Cacheable[] cacheable() default {};//多个Cacheable类型注解
    
        CachePut[] put() default {};//多个CachePut类型注解
    
        CacheEvict[] evict() default {};//多个CacheEvict类型注解
    

三.总结

zhangfeng

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: