Spring Cache对Cache
进行了抽象,提供了@Cacheable
、@CachePut
、@CacheEvict
等注解。SpringBoot应用基于SpringCache
,既提供了基于内存实现的缓存管理器,可以用于单体应用系统,也集成了Redis、EhCache等缓存服务器,可用于大型系统或者分布式系统。
Cache
应用系统缓存通常有以下作用:
- 缓存Web系统的输出,如伪静态页面
- 缓存系统中不经常改变的业务数据,如用户权限、字典数据、配置信息等
Cache的组件和概念
CacheManager
,用来创建、管理、管理多个命名唯一的Cache,如组织机构缓存、菜单项的缓存、菜单树的缓存等Cache
类似Map那样的Key-Value
存储结构,Value部分通常包含了缓存的对象,通过Key来取得缓存对象缓存项
,存放在缓存里的对象,常常需要实现序列化接口,以支持分布式缓存Cache存储方式
,缓存组件可以将对象放到内存或其他缓存服务器上,Spring Boot提供了一个基于ConcurrentMap
的缓存,同时也集成了Redis、EhCache2.x、JCache缓存服务器等缓存策略
,通常Cache还可以有不同的缓存策略,如设置缓存最大的容量
,缓存项的过期时间
等分布式缓存
,缓存通常按照缓存数据类型存放在不同缓存服务器上,或者同一类型的缓存按照某种算法、不同Key的数据存放在不同的缓存服务器上Cache Hit
,从Cache中取得期望的缓存项,我们通常称之为缓存命中。如果没有命中则称之为Cache Miss
,意味着需要从数据来源处重新取出井放回Cache中Cache Miss
,缓存丢失,根据Key没有从缓存中找到对应的缓存项Cache Evication
,缓存清除操作Hot Data
,热点数据,缓存系统能调整算法或者内部存储方式,使得最有可能频繁访问的数据能被尽快访问到On-Heap
, Java分配对象都是在堆内存中,有最快的获取速度。由于虚拟机的垃圾回收管理机制,缓存放入过多的对象会导致垃圾回收时间过长,从而有可能影响性能off-Heap
,堆外内存,对象存放在虚拟机分配的堆外内存中,因此不受垃圾回 收管理机制的管理,不影响系统性能,但堆外内存的对象要被使用,还要序列化成堆内对象。很多缓存工具会把不常用的对象放到堆外,把热点数据放到堆内
Cache的单体应用
使用专有的Cache服务器
使用一二级缓存服务器
Spring Boot Cache
Spring Boot本身提供了一个基于ConcurrentHashMap
的缓存机制,也集成了EhCache2.x、JCache CJSR-107、EhCache3.x、 Haz巳least、Infinispan),还有 Couchbase、Redis等。
Spring Boot应用通过注解的方式使用统一的缓存,只需在方法上使用缓存注解即可,其缓存的具体实现依 赖于选择的目标缓存管理器。
使用@Cacheable
集成 Spring Cache
依赖:
1 | <dependency> |
appliaction.properties 中配置
1 | spring.cache.type=Simple |
Simple
,基于ConcurrentHashMap
实现的缓存,适合单体应用或者开发环境使用none
,关闭缓存,比如开发阶段为了确保功能正确, 可以先禁止使用缓存redis
,使用 Redis作为缓存,还需要在pom
中增加 Redis依赖Generic
,用户自定义缓存实现,用户需要实现一个org.springframework.cache.CacheManager
的实现- 其他还有 JCache、 EhCache2.x, Hazelcast等
注解@EnableCaching
打开缓存功能
注释驱动缓存
@Cacheable
注解@Cacheable声明了方法的结果是可缓存的,如果缓存存在,则目标方法不会被调用,直接取出缓存。
可以为方法声明多个缓存
,如果至少有一个缓存有缓存项,则其缓存项将被返回。
Key生成器
Spring使用了KeyGenerator
类来根据方法参数生成 Key
@CachePut
注解CachePut
总是会执行方法体,井且使用返回的结果更新缓存
@CacheEvict
注解CacheEvict 用于删除缓存项或者清空缓存,CacheEvict 可以指定多个缓存名字来清空多个缓存
CacheEvict可以清空缓存中的所有项目,此时使用allEntries=true
来删除清空缓存
@Caching
注解Caching可以混合以上各种注解,可以在Caching标签中混合@Cacheable、@CachePut、@CacheEvict
@CacheConfig
Cache注解都需要提供Cache名称,如果每个Service方法上都包含 Cache名称,可能写起来重复。
注解 CacheConfig
作用于类上,可以为此类的方法的缓存注解提供默认值,包括:
- 缓存的默认名称
- 缓存的 KeyGenerator
使用 RedisCache
集成Redis缓存
pom
1 | <dependency> |
配置application.properties
:
1 | spring.cache.type=REDIS |
禁止缓存
通常在开发环境下,不需要使用Redis类型的缓存,你可以配置为Simple,动切换,用HashMap作为缓存,或者使用None禁止缓存以方便开发。
定制缓存
对于 RedisCacheManager来说,还可以定制缓存项的存活时间,缓存名是否在Redis中加上前缀等,这是通过实现CacheManagerCustomizer配置来完成定制
Redis 缓存原理
SpringBoot的自动配直类RedisCacheConfiguration会自动检测 spring.cache.type的值,从而决定使用何种缓存。