JSR-107、Spring缓存抽象、整合Redis

一、JSR-107

Java Caching 定义了五个核心接口,分别是 CachingProviderCacheManagerCaheEntryExpiry

  • CachingProvider定义了创建、配置、获取、管理和控制多个 CacheManager。一个应用可以在运行期间访问多个 CachingProvider。
  • CacheManager 定义了创建、配置、获取、管理和控制多个唯一命名的 Cache,这些 Cahce 存在 CacheManager 的上下文。一个 CacheManager 仅被一个 CachingProdiver 所拥有。
  • Cache 是一个类似 map 的数据结构并临时存储以 Key 为索引的值。一个 Cache 仅被一个 CacheManager 拥有。
  • Entry 是存储在 Cache 中的 key-value 对
  • Expiry 每一个存储在 Cache 中的条目有一个定义的有效期。一旦超过这个时间,条目为过期状态。一旦过期,条目不可访问、更新和删除。缓存有效期可以通过 ExpiryPolicy 设置。

结构图

二、Spring 缓存抽象

Spring 从 3.1 开始定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager接口来统一不同的缓存技术;并支持使用JCache(JSR-107)注解简化我们开发;

  • Cache 接口为缓存的组件规范定义,包含缓存的各种操作集合;
  • Cache 接口下 Spring 提供了各种 xxxCache 的实现,如 RedisCache、EhCache,ConcurrentCache 等;
  • 每次调用需要缓存功能的方法时,Spring 会检查指定参数的指定的目标方法是否已经被调用过;如果有就直接存缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户,下次调用直接从缓存中获取。
  • 使用 Spring 缓存抽象时 我们需要关注两点:
    • 确定方法需要被缓存以及他们的缓存策略
    • 从缓存中读取之前缓存存储的数据

缓存

三、几个重要概念、缓存注解

注解 描述
Cache 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等
CacheManager 缓存管理器,管理各种缓存组件
@Cacheable 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
@CacheEvict 清空缓存
@CachePut 保证方法被调用,又希望结果被缓存
@EnableCaching 开启基于缓存的注解
keyGenerator 缓存数据时key生成策略
serialize 缓存数据时value序列化策略

四、简单分析缓存原理

concurrentMapCacheManager

getCache

findInCache

findCacheItem

  1. CacheAutoConfiguration会在启动时,注入存在的 CacheConfigration,默认采用的是 SimpleCacheConfiguration
  2. SimpleCacheConfiguration:cacheManager() 方法,可以看到会注入一个 ConcurrentMapCacheManager
  3. ConcurrentMapCacheManager: getCache() 是用 concurrentMap 来存储的,首次调用的时候,如果没有该数据,会调用createConcurrentMapCache
  4. @Cacheable:
    1. 方法运行之前,先去查询 Cache (缓存组件),按照 cacheNames 指定的名字获取;CacheManager先获取相应的缓存,第一次获取缓存如果没有 Cache 组件自动创建
    2. 去 Cache 中查找缓存的内容,使用一个 key,默认就是方法的参数,key 是按照某种策略生成的,默认是keyGenerator生成的
    3. 没有查到缓存就调用目标方法
    4. 将目标方法返回的结果,放进缓存中