一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
Spring Cache是Spring体系下标准化缓存框架,支持缓存品种多,常见缓存Redis、EhCache、Caffeine均支持。它们之间既能独立使用,也能组合使用。
Spring内部支持的缓存,可实现无缝平滑迁移,无需修改业务逻辑。注解缓存的实现依赖于动态代理。
大多数情况下使用的是注解版、少数情况下也能使用编程版。注解版与业务代码高度解藕,因其依托动态代理技术实现,使用场景上有一定的限制。编程版嵌入业务代码,代码顺序执行,无前置使用条件。
1.基本概念
1.1 缓存管理器
一个应用可以有多个缓存管理器,每个缓存管理器可以有多个缓存,每个缓存可以存储多条记录。
缓存的存储介质不同、缓存连接不同的数据库、缓存值序列化等由缓存管理器配置。缓存管理器有主次之分,默认情况下使用主(首要)缓存管理器。
在SpringBoot中,数据的缓存管理存储依赖于Spring框架中cache相关的org.springframework.cache.Cache和org.springframework.cache.CacheManager缓存管理器接口。
如果程序中没有定义类型为CacheManager的Bean组件或者是名为cacheResolver的CacheResolver缓存解析器,Spring Boot将尝试选择并启用以下缓存组件(按照指定的顺序):
(1)Generic
(2)JCache (JSR-107)(EhCache 3、Hazelcast、Infinispan等)
(3)EhCache 2.x
(4)Hazelcast
(5)Infinispan
(6)Couchbase
(7)Redis
(8)Caffeine
(9)Simple
(10)NoOp
上面按照Spring Boot缓存组件的加载顺序,列举了支持的10种缓存组件,在项目中添加某个缓存管理组件(例如Redis)后,Spring Boot项目会选择并启用对应的缓存管理器。
如果项目中同时添加了多个缓存组件,且没有指定缓存管理器或者缓存解析器(CacheManager或者cacheResolver),那么Spring Boot会按照上述顺序在添加的多个缓存中优先启用指定的缓存组件进行缓存管理。
Spring Boot默认缓存管理中,没有添加任何缓存管理组件能实现缓存管理。这是因为开启缓存管理后,Spring Boot会按照上述列表顺序查找有效的缓存组件进行缓存管理,如果没有任何缓存组件,会默认使用Simple缓存组件进行管理。
Simple缓存组件是Spring Boot默认的缓存管理组件,它默认使用内存中的ConcurrentMap进行缓存存储,所以在没有添加任何第三方缓存组件的情况下,可以实现内存中的缓存管理,但是我们不推荐使用这种缓存管理方式。
当在Spring Boot默认缓存管理的基础上引入Redis缓存组件,即在pom.xml文件中添加Spring Data Redis依赖启动器后,SpringBoot会使用RedisCacheConfigratioin当做生效的自动配置类进行缓存相关的自动装配,容器中使用的缓存管理器是RedisCacheManager, 这个缓存管理器创建的Cache为 RedisCache, 进而操控redis进行数据的缓存。
依赖:org.springframework.boot 和 spring-boot-starter-data-redis\
1.2 缓存配置类
(1)缓存配置类:SpringBoot提供了10个配置类,对应上面介绍的那 10 个缓存组件,其中SimpleCacheConfiguration是默认配置类
org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration
org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration
org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration
org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration
org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration
org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration
org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration
org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration
org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration // 默认
org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration
(2)SpringBoot各类缓存优先级:默认使用默认缓存,当导入其他依赖则默认缓存失效,导入多种依赖,则按照上面排序生效其中一个,源码判断如下:
// 源码
@ConditionalOnMissingBean({CacheManager.class})
@Conditional({CacheCondition.class})
class SimpleCacheConfiguration {
SimpleCacheConfiguration() {
}
源码中,使用了注解@ConditionalOnMissingBean,其作用是:判断当前需要注入Spring容器中的bean的实现类是否已经含有,有的话不注入,没有就注入(被覆盖)。当注入其他缓存后,会在容器中注入对应缓存的CacheManager,此时,由于上述注解的原因,默认缓存则不再生效。
1.3 缓存
Cache是一组配置相同缓存的集合,可以理解为命名空间,Spring Cache体系下的缓存生命时间是以Cache为单位的,不支持以Key为单位设置生存时间。不同的业务对应不同的缓存配置,应在缓存处予以区分。
CacheName应具有显著的业务区分度以及过期时间区分度,并且以全局常量的方式提供,采取集中化管理的方式,禁止采用魔术变量的方式指定CacheName。
缓存结构:Cache结构是一个map: ConcurrentMap<Object, Object>,一般来说缓存的Key与Value均是String类型,特别是Value通常序列化成JSON串。
核心思想:
当我们调用一个方法时会把该方法的参数和返回结果作为一个键值对存放在缓存中,等下次利用同样的参数来调用该方法时将不会再执行,而是直接从缓存中获取结果进行返回。 理解:
SpringBoot 的缓存机制是通过切面编程 aop 来实现的。