ContiNew
缓存

Spring Cache

continew-starter-cache-springcache 基于 Spring Cache 抽象提供单级 Redis 缓存,自动配置 RedisCacheManager 并解决 Jackson 序列化乱码问题,引入即用。

continew-starter-cache-springcache 基于 Spring Cache 提供 Redis 缓存实现,在 Redisson 之上完成 @Cacheable 等声明式缓存的自动配置,无需手动配置 RedisCacheManager,开箱即用。

引入依赖

<dependency>
    <groupId>top.continew.starter</groupId>
    <artifactId>continew-starter-cache-springcache</artifactId>
</dependency>

配置

本模块无专属配置属性类,缓存过期策略复用 Spring Boot 原生 spring.cache.* 配置,默认值由模块内置的 default-cache-springcache.yml 提供。

spring:
  cache:
    redis:
      # 缓存过期时长(单位:毫秒,Spring Boot 默认 -1 表示永不过期,模块内置默认 2 小时)
      time-to-live: 7200000
      # 是否允许缓存空值(默认 true,允许缓存空值可缓解缓存穿透)
      cache-null-values: true
配置项说明模块内置默认值
spring.cache.redis.time-to-live缓存过期时长(毫秒)7200000(2 小时)
spring.cache.redis.cache-null-values是否允许缓存空值true

使用 Spring Cache 注解

引入依赖后,直接使用 Spring Cache 标准注解即可,缓存值以 Jackson JSON 序列化存入 Redis(SpringCacheAutoConfiguration 中配置了 StringRedisSerializer 序列化 Key、GenericJacksonJsonRedisSerializer(Jackson 3)序列化 Value,解决了 Jackson 解析缓存乱码问题)。

@Service
public class DemoService {

    @Cacheable(cacheNames = "demo", key = "'id:' + #id")
    public DemoVO get(Long id) {
        // 首次执行后结果缓存至 Redis,过期策略取 spring.cache.redis 配置
        return ...;
    }

    @CacheEvict(cacheNames = "demo", key = "'id:' + #id")
    public void update(DemoReq req) {
        // ...
    }
}

未指定 key 时,使用模块内置的 KeyGenerator 生成缓存 Key:方法名(下划线分隔后大写)+ : + 方法参数 JSON 的 SHA-256 摘要(见 SpringCacheAutoConfiguration.keyGenerator)。

序列化行为与升级

序列化配置见 SpringCacheAutoConfiguration.redisCacheConfiguration。Key 使用 StringRedisSerializer,Value 使用 GenericJacksonJsonRedisSerializer(Jackson 3)并启用多态类型信息。3.0.0 起 Long、不可变集合、Map 等根值携带多态类型 id(@class),String、Integer、Boolean、Double 等少数基础类型不携带(Spring Data Redis 既有设计)。int 范围内的 Long 根值读回保持 Long,List.of()、Stream.toList() 等不可变集合根值可正常读回。byte[] 根值的写出编码由裸 Base64 字符串变为携带类型 id,读回仍为 byte[] 且内容不变。

JDK 不可变与包装 Map 实现(如 Map.of() 产物、Collections.unmodifiableMap 结果)的根值写入前会浅拷贝为 LinkedHashMap,读回为 LinkedHashMap,内容与原值等价,依赖原实现类型的调用方需自行转换。用户自定义的 Map 子类不受影响,读回保持原类型与条目。第三方不可变 Map(如 Guava ImmutableMap)按原实现类名写出,读回会显式抛出反序列化异常(与 2.x 行为一致),不存在静默污染。

从 2.x 升级到 3.0.0 时,Spring Cache 缓存值的存量数据无需清理。2.x GenericJackson2JsonRedisSerializer 写入的多态类型编码与 3.0.0 兼容,常见值类型已做双向读写验证。

多态类型信息基于 allowIfBaseType(Object.class) 校验(既有设计),Redis 缓存应视为可信边界,缓存键空间不得由不可信输入写入。存在不可信数据来源时,请自行收紧 PolymorphicTypeValidator 白名单。

本模块依赖 continew-starter-cache-redisson,可一并使用其 RedisUtils、RedisLockUtils 工具类(见 Redisson 子页)。

核心依赖

依赖描述
top.continew.starter:continew-starter-cache-redissonRedisson 缓存支撑模块(Redis 客户端及分布式工具)
cn.hutool:hutool-cryptoHutool 加密模块(用于缓存 Key 生成的 SHA-256 摘要)

目录