spring-cache
简介
Spring官方提供的基于注解的缓存支持,可以通过注解配置方式低侵入的给原有Spring应用增加缓存功能,提高数据访问性能。
Spring定义的缓存抽象接口
org.springframework.cache.Cache
说明:缓存的组件规范定义,包含缓存的各种操作集合
实现:RedisCache、EhCacheCache、ConcurrentMapCache等
org.springframework.cache.CacheManager
说明:缓存管理器的组件规范定义,管理各种缓存(Cache)组件
实现:RedisCacheManager、EhCacheCacheManager、SimpleCacheManager等
org.springframework.cache.interceptor.KeyGenerator
说明:缓存数据时key生成策略
实现:SimpleKeyGenerator(Spring默认实现)、自定义实现
Java Caching(JSR107)标准
定义的核心接口
CachingProvider:定义了创建、配置、获取、管理和控制多个CacheManager。一个应用可 以在运行期访问多个CachingProvider。
CacheManager:定义了创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache 存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。
Cache:是一个类似Map的数据结构并临时存储以Key为索引的值。一个Cache仅被一个 CacheManager所拥有。
Entry:是一个存储在Cache中的key-value对。
Expiry:每一个存储在Cache中的条目有一个定义的有效期。一旦超过这个时间,条目为过期 的状态。一旦过期,条目将不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。
特性
声明式缓存注解
@Cacheable:主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
@CachePut:保证方法被调用,又希望结果被缓存
@CacheEvict:清空缓存
@EnableCaching:开启基于注解的缓存
缓存注解参数说明
缓存注解SpEL说明
缺点
不支持在缓存注解上设置细粒度的缓存过期时间(只支持通过CacheManager给同类别缓存(相同cacheNames的缓存)统一设置过期时间(jetcache支持)
不支持二级缓存(jetcache支持)
不支持分布式缓存自动刷新(jetcache支持)
不支持分布式缓存热点缓存重建时保护机制(多个线程同时重建缓存问题)(jetcache支持)
使用
引入依赖
开启缓存:@EnableCaching
配置Redis连接
定义CacheManager(可选)
定义KeyGenerator(可选)
方法上使用相关缓存注解
原理
关键原理就是 Spring AOP,通过 Spring AOP,其实现了在方法调用前、调用后获取方法的入参和返回值,进而实现了缓存的逻辑。
如果需要分析自动配置的原理就需要分析自动配置类:CacheAutoConfiguration
这个自动配置中导入了一个类CacheConfigurationImportSelector,这个类会引入一些缓存配置类
在配置文件中设置属性debug=true,这样就会打印所有的配置报告
通过打印日志可以看出SimpleCacheConfiguration配置类默认生效。这个配置类给容器中注册了一个CacheManager
缓存方法运行之前,先按照cacheNames查询缓存组件,第一次获取缓存如果没有缓存创建一个
Cache中查找缓存的内容会使用一个key,默认就是方法的参数。如果没有参数使用SimpleKey生成
参考
https://blog.csdn.net/weixin_36279318/article/details/82820880
JetCache
简介
JetCache是一个基于Java的缓存系统封装,提供统一的API和注解来简化缓存的使用。
JetCache提供了比SpringCache更加强大的注解,可以原生的支持TTL、两级缓存、分布式自动刷新,还提供了Cache接口用于手工缓存操作。
当前有四个实现,RedisCache、TairCache(此部分未在github开源)、CaffeineCache(in memory)和一个简易的LinkedHashMapCache(in memory),要添加新的实现也是非常简单的。
特性
支持在缓存注解上缓存过期时间
支持二级缓存(Caffeine)
支持分布式缓存自动刷新
支持分布式缓存热点缓存重建时保护机制(多个线程同时重建缓存问题)
通过注解创建并配置Cache实例
针对所有Cache实例和方法缓存的自动统计
Key的生成策略和Value的序列化策略是可以配置的
缺点
不支持缓存批量清除(spring-cache支持)
二级缓存不支持在多个应用节点上同步清除?
注解
注解说明
@CreateCache:添加缓存(用在对象上,手动调用缓存API)
@Cached:添加缓存
@CacheUpdate:更新缓存
@CacheInvalidate:移除缓存(不支持批量移除,只支持单个)
@CacheRefresh:分布式缓存自动刷新
@CachePenetrationProtect:分布式缓存重建保护(防止多线程同时创建缓存)
注解参数
全局配置
使用
引入依赖
设置配置
缓存生效注解
缓存实例使用
缓存注解使用
原理
基于Spring AOP对方法调用前和方法调用后拦截,增加对缓存的操作
入口注解类EnableMethodCache和EnableCreateCacheAnnotation
核心代码
RedisCache: redis实现,使用jedis客户端
RedisLettuceCache: redis实现,使用lettuce客户端
CaffeineCache: 基于内存的缓存,使用Caffeine
LinkedHashMapCache: 自制的简易内存缓存,没有任何依赖
LoadingCache:基于Decorator模式,提供自动加载功能
RefreshCache:基于Decorator模式,提供自动刷新功能
MultiLevelCache:多级缓存,注解方式配置只支持了两级,实际上这个类支持N级
参考
https://github.com/alibaba/jetcache/wiki/Home_CN
layering-cache
简介
layering-cache是一个支持分布式环境的多级缓存框架,使用方式和spring-cache类似。
一级缓存使用Caffeine作为本地缓存,二级缓存使用redis作为集中式缓存。
一级缓存和二级缓存的数据一致性是通过推和拉两种模式相结合的方式来实现的。
推主要是基于redis的pub/sub机制,拉主要是基于消息队列和记录消费消息的偏移量来实现的
特性
支持缓存命中率的监控统计,统计数据上报支持自定义扩展
内置dashboard,支持对缓存的管理和缓存命中率的查看
支持二级缓存(Caffeine)
支持缓存过期时间在注解上直接配置
支持缓存的自动刷新(当缓存命中并发现二级缓存将要过期时,会开启一个异步线程刷新缓存)
缓存Key支持SpEL表达式
Redis支持Kryo、FastJson、Jackson、Jdk和Protostuff序列化,默认使用Protostuff序列化,并支持自定义的序列化
支持同一个缓存名称设置不同的过期时间
支持禁用一级缓存,只使用二级缓存
通过允许存空值来解决缓存穿透问题
注意点
ayering-cache支持同一个缓存名称设置不同的过期时间,但是一定要保证key唯一,否则会出现缓存过期时间错乱的情况
删除缓存的时候会将同一个缓存名称的不同的过期时间的缓存都删掉
在集成layering-cache之前还需要添加以下的依赖,主要是为了减少jar包冲突(依赖jar列表)。
redis的key序列化方式必须StringRedisSerialize
注解
注解说明
@Cacheable:缓存查询结果
@FirstCache:一级缓存配置项
@SecondaryCache:二级缓存配置项
@CachePut:更新缓存数据
@CacheEvict:删除缓存
@EnableLayeringCache:启用缓存组件
注解参数
原理
https://github.com/xiaolyuh/layering-cache/wiki/%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86
参考
https://github.com/xiaolyuh/layering-cache
https://github.com/xiaolyuh/layering-cache/wiki/%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86