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=存储的值