==作者:YB-Chi==
[toc]
Caffeine介绍
Caffeine是基于Java 1.8的高性能本地缓存库,由Guava改进而来,而且在Spring5开始的默认缓存实现就将Caffeine代替原来的Google Guava,官方说明指出,其缓存命中率已经接近最优值。实际上Caffeine这样的本地缓存和ConcurrentMap很像,即支持并发,并且支持O(1)时间复杂度的数据存取。二者的主要区别在于:
ConcurrentMap将存储所有存入的数据,直到你显式将其移除;
Caffeine将通过给定的配置,自动移除“不常用”的数据,以保持内存的合理占用。
因此,一种更好的理解方式是:Cache是一种带有存储和移除策略的Map。
引入依赖
1 | <dependency> |
集成springboot
1 | <dependency> |
Caffeine配置说明
参数 | 类型 | 描述 |
---|---|---|
initialCapacity | integer | 初始的缓存空间大小 |
maximumSize | long | 缓存的最大条数 |
maximumWeight | long | 缓存的最大权重 |
expireAfterAccess | duration | 最后一次写入或访问后,指定经过多长的时间过期 |
expireAfterWrite | duration | 最后一次写入后,指定经过多长的时间缓存过期 |
refreshAfterWrite | duration | 创建缓存或者最近一次更新缓存后,经过指定的时间间隔后刷新缓存 |
weakKeys | boolean | 打开 key 的弱引用 |
weakValues | boolean | 打开 value 的弱引用 |
softValues | boolean | 打开 value 的软引用 |
recordStats | - | 开发统计功能 |
注意:
weakValues
和softValues
不可以同时使用。maximumSize
和maximumWeight
不可以同时使用。expireAfterWrite
和expireAfterAccess
同时存在时,以expireAfterWrite
为准。
注解说明
- @EnableCaching:开启基于注解的缓存-
- @Cacheable:表示该方法支持缓存。当调用被注解的方法时,如果对应的键已经存在缓存,则不再执行方法体,而从缓存中直接返回。当方法返回null时,将不进行缓存操作。
- @CachePut:表示执行该方法后,其值将作为最新结果更新到缓存中,每次都会执行该方法。
- @CacheEvict:表示执行该方法后,将触发缓存清除操作。
- @Caching:用于组合前三个注解
@EnableCaching
1 | import org.springframework.boot.SpringApplication; |
@Cacheable
- cacheNames/value:指定缓存组件的名字,数组形式
- key:缓存数据使用的key,确定缓存可以用唯一key进行指定;eg:编写SpEL; #id,参数id的值 ,,#a0(第一个参数), #p0(和a0的一样的意义) ,#root.args[0]
- keyGenerator:key的生成器;可以自己指定key的生成器的组件id(注意: key/keyGenerator:二选一使用;不能同时使用)
- cacheManager:指定缓存管理器;或者cacheResolver指定获取解析器
- condition:指定符合条件的情况下才缓存;使用SpEl表达式,eg:condition = “#a0>1”:第一个参数的值>1的时候才进行缓存
- unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;eg:unless = “#a0!=2”:如果第一个参数的值不是2,结果不缓存;
- sync:是否使用异步模式
1 |
|
这里也可以使用自定义的keyGenerator,使用属性keyGenerator = “myKeyGenerator
定义一个@Bean类,将KeyGenerator添加到Spring容器
1 |
|
@CachePut
@CachePut注解也是一个用来缓存的注解,不过缓存和@Cacheable有明显的区别是既调用方法,又更新缓存数据,也就是执行方法操作之后再来同步更新缓存,所以这个主键常用于更新操作,也可以用于查询,主键属性和@Cacheable有很多类似的,详情参看@CachePut源码
1 | /** |
@CacheEvict
- key:指定要清除的数据
- allEntries = true:指定清除这个缓存中所有的数据
- beforeInvocation = false:默认代表缓存清除操作是在方法执行之后执行
- beforeInvocation = true:代表清除缓存操作是在方法运行之前执行
1 |
|
@Caching
@Caching 用于定义复杂的缓存规则,可以集成@Cacheable和 @CachePut
1 | // @Caching 定义复杂的缓存规则 |
附录拓展:SpEL表达式用法
Cache SpEL available metadata
名称 | 位置 | 描述 | 示例 |
---|---|---|---|
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 | 执行上下文(avaluation context) | 当前被调用的方法的参数,如findArtisan(Artisan artisan),可以通过#artsian.id获得参数 | #artsian.id |
result | 执行上下文(evaluation context) | 方法执行后的返回值(仅当方法执行后的判断有效,如 unless cacheEvict的beforeInvocation=false) | #result |
实战
@Cacheable,查询用户功能,走了缓存就不走方法
1 |
|
@CachePut,注册用户功能,走方法也更新缓存
1 |
|
@CacheEvict,标记用户删除状态,删除指定缓存,默认缓存清除操作是在方法执行之后执行
1 |
|