Spring缓存抽象概述
Spring框架自身并没有实现缓存解决方案,但是从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口,提供对缓存功能的声明,能够与多种流行的缓存实现集成。
Cache接口为缓存的组件规范定义,包含缓存的各种操作集合;
Cache接口下Spring提供了各种xxxCache的实现:如RedisCache,EhCacheCache , ConcurrentMapCache等;
CacheManager接口为缓存管理器规范,简单来说就是用于存放cache,Spring默认也提供了一些列管理器的实现。
Spring缓存抽象提供了5个注解用来声明缓存规则:
@Cacheable:能够根据方法的请求参数对其结果进行缓存,多用于查询
@CachePut: 执行方法,并缓存结果
@CacheEvict:清空缓存
@Caching:能够同时应用多个缓存注解功能
@CacheConfig: 用于抽取缓存的公共配置(类级别)
以上5个注解除了@CacheConfig注解是类级别的注解,其余4个注解在类和方法上均可以使用,作用在类上表示对该类下所有方法生效,作用的方法上只对该方法生效,且只能用于public修饰的符方法,protected或者private修饰的方法不适用。
@Cacheable注解@Cacheable注解的作用是Spring在调用该方法之前,首先在缓存中查找方法的返回值,默认的key是根据参数值生成,如果存在,直接返回缓存中的值,否则执行该方法,并将返回值保存到缓存中
@Cacheable运行流程:1.方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的名字获取;
(CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建。
2.去Cache中查找缓存的内容,使用一个key,默认就是方法的参数值;
key是按照某种策略生成的;默认是使用keyGenerator生成的,
Spring默认加载的是SimpleCacheManage,SimpleKeyGenerator生成key的默认策略是:
如果没有参数;key=new SimpleKey()
如果有一个参数:key=参数的值
如果有多个参数:key=new SimpleKey(params)
3.没有查到缓存就调用目标方法;
4.将目标方法返回的结果,放进缓存中
@Cacheable属性说明:1.acheNames/value:该属性值必须提供,指定缓存组件的名字,将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存;
如:cacheNames = "product"或者cacheNames = {"product1","product2"}
2.key:缓存数据使用的key,不指定key则默认是使用方法参数的值该属性值支持SpEL表达式
3.cacheManager:指定缓存管理器;或者cacheResolver指定获取解析器
4.condition:指定符合条件的情况下才缓存
5.unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;可以获取到结果进行判断
unless = "#result == null"
unless = "#a0==2":如果第一个参数的值是2,结果不缓存;
6.sync:是否使用异步模式
使用示例:
1 @Cacheable(cacheNames = "product")// 默认key为参数,多个参数SimpleKey [arg1,arg2]
2 //@Cacheable(cacheNames = "product",key = "#root.methodName+'['+#id+']'")
3 //@Cacheable(cacheNames = "product",keyGenerator = "myKeyGenerator")
4 //@Cacheable(cacheNames = "product",key = "#root.methodName+'['+#id+']'",condition="#a0>10",unless = "#a0==11") //带条件的缓存满足condition=true缓存,满足unless=true则不缓存
5 public Product getProductById(Long id){
6 Product product =productMapper.getProductById(id);
7 System.out.println(product);
8 return product;
9 }
10 //指定key属性值
11 @Cacheable(cacheNames ="product", key="#id") //”#+参数名”的形式,直接使用参数名
12 //或者
13 //@Cacheable(cacheNames ="product", key="#a0") //”#a+参数位置”的形式
14 public Product getProductById(long id) {
15
xxxx
16 }
17 @Cacheable(cacheNames ="product", key="# productcondition.productId")
18 //或者
19 //@Cacheable(cacheNames ="product", key="#a0.productId")
20 public Product getProduct (Product productcondition) {
21
xxxx
22 }