spring 定义了 org.springframework.cache.CacheManager和org.springframework.cache.Cache接口用来统一不同的缓存技术。
- CacheManager是spring提供的抽象接口
- Cache接口包含缓存的各种操作(crud)
CacheManager的实现
| CacheManager | 描述 |
|---|---|
| SimpleCacheManager | 使用简单的Collection |
| ConcurrentMapCacheManager | 使用简单的ConcurrentMap(sptingboot默认实现) |
| NoOpCacheManager | 金测试用途,不会实际存储缓存 |
| EhCacheCacheManager | 使用EhCache |
| GuavaCacheManager | 使用Google Guava的GuavaCache |
| HazelcastCacheManager | 使用Hazelcast |
| JCacheCacheManager | 支持JCache(JSR-107)标准的实现作为缓存技术,如Apache Commons JCS |
| RedisCacheManager | 使用redis作为缓存技术 |
利用RedisCacheManager实现Cache
项目中使用spring-data-redis-1.8.9.RELEASE.jar版本,不同版本之间会有不同地实现。(此版本支持默认过期时间)
需要注册一下CacheManager的Bean
|
|
声明式缓存注解
| 注解 | 解释 |
|---|---|
| @Cacheable | 在方法执行前Spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放进缓存 |
| @CacheEvict | 将一条或多条数据从缓存中删除 |
| @CachePut | 无论怎样,都会将方法的返回值放到缓存。 |
| @Caching | Cacheable、CachePut、CacheEvict的组合注解 |
| @CacheConfig | 配置当前类中使用到的公共参数部分 |
1. @Cacheable例子
|
|
会在redis中存储两份数据结构
一份是zset
123key=cache_zset~keysvalue=cache_pre:#a_#b_#cscore=0另一份是string
12key=cache_pre:#a_#b_#cvalue=存储的值
常用几个参数说明
| 参数 | 说明 | 例子 |
|---|---|---|
| value | 存入的缓存的名称 | |
| cacheNames | 和value相同 | |
| key | 根据传入的参数生成的对应方法的缓存值 | |
| condition | 缓存的条件 | condition="#a==1"代表只有传入值a等于1时才缓存数据 |
| unless | 不缓存的条件,方法执行后触发 | unless="#result==null"代表返回值空时不缓存数据 |
2. @CacheEvit例子
|
|
常用几个参数说明
| 参数 | 说明 | 例子 |
|---|---|---|
| value | 存入的缓存的名称 | |
| cacheNames | 和value相同 | |
| key | 根据传入的参数生成的对应方法的缓存值 | |
| condition | 缓存的条件 | condition="#a==1"代表只有传入值a等于1时才缓存数据 |
| allEntries | 是否删除全部缓存,默认false | true时不管condition直接删除@Cacheable的value值 |
| beforeInvocation | 是否方法调用之前删除 默认false | 建议方法调用后且没有异常退出时删除缓存 |
3.@CachePut例子
和@Cacheable类似,不过@CachePut每次都会执行方法,而@Cacheable先查询缓存如果缓存没值才执行方法
|
|
常用几个参数说明
| 参数 | 说明 | 例子 |
|---|---|---|
| value | 存入的缓存的名称 | |
| cacheNames | 和value相同 | |
| key | 根据传入的参数生成的对应方法的缓存值 | |
| condition | 缓存的条件 | condition="#a==1"代表只有传入值a等于1时才缓存数据 |
| unless | 不缓存的条件,方法执行后触发 | unless="#result==null"代表返回值空时不缓存数据 |
4.@Caching例子
|
|
5.@CacheConfig例子
如果在类中定义了@CacheConfig那么此类下的所有value=”xyz”就共用此config的cacheNames
其他问题
key如果不分配时会出现org.springframework.cache.interceptor.SimpleKey cannot be cast to java.lang.String
找到Cache配置类继承并重写keyGenerator方法,让它有自动生成key策略
会在redis中存储两份数据结构
一份是zset
123key=cache_zset~keysvalue=com.example.facade.impl.CacheFacadeImpllist#a#b#c //生成key策略导致的score=0另一份是string
12key=com.example.facade.impl.CacheFacadeImpllist#a#b#cvalue=存储的值