Spring Boot + Redis 缓存学习笔记
1️⃣ @Cacheable 基本理解
示例:
@Cacheable(value = CacheConstants.ROLE_DETAILS, key = "#key", unless = "#result.isEmpty()")
public List<SysRole> listRolesByRoleIds(List<Long> roleIdList, String key) {
return baseMapper.selectByIds(roleIdList);
}
-
作用:方法调用前先从缓存读取数据,如果有直接返回缓存,否则执行方法并缓存结果。
-
参数说明:
value:缓存名称,对应 Redis key 前缀。key:缓存键,可使用 SpEL 表达式。unless:缓存条件,例如#result.isEmpty()表示结果为空时不缓存。
✅ 作用:加速查询,减少数据库压力。
2️⃣ CacheManager 与 RedisTemplate 区别
- RedisTemplate:操作 Redis 的工具类,可手动 get/set/hash/list 等。
- RedisCacheManager:Spring Cache 抽象层,管理所有缓存,
@Cacheable/@CacheEvict依赖它。 - 关系:CacheManager 底层可以用 RedisTemplate 或 LettuceConnectionFactory,但 RedisTemplate 可独立使用。
3️⃣ TTL(缓存过期时间)设置策略
数据类型与 TTL 建议
| 数据类型 | TTL 建议 |
|---|---|
| 静态字典 / 角色 / 设备类型 | 1h ~ 24h 或手动刷新 |
| 热点业务数据 | 5min ~ 1h |
| 高频变动业务数据 | 30s ~ 5min |
💡 原则:TTL 不宜太长导致脏数据,也不宜太短造成缓存击穿。大厂通常结合 TTL + 主动刷新。
4️⃣ CacheManager 多 cacheName TTL 管理
-
大厂做法:
- 单个 RedisCacheManager 管理所有缓存
- 不同 cacheName 可以单独配置 TTL
- @Cacheable/@CacheEvict 指定 cacheName
示例:
Map<String, RedisCacheConfiguration> cacheConfigs = new HashMap<>();
cacheConfigs.put("deviceTypes", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(6)));
cacheConfigs.put("roleDetails", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(12)));
cacheConfigs.put("hotOrders", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)));
5️⃣ 序列化器对比
| 特性 | GenericJackson2JsonRedisSerializer | 自定义 Jackson2JsonRedisSerializer |
|---|---|---|
| 类信息 | 自动保存 @class | 需要 activateDefaultTyping |
| 可配置性 | 低 | 高(日期、字段可见性、模块等) |
| 使用场景 | 简单缓存、@Cacheable 对象 | 复杂对象、手动 RedisTemplate 使用 |
| 兼容性 | 与 Spring Cache 默认配合好 | 需保证 CacheManager 序列化器一致 |
💡 实务建议:
- CacheManager + @Cacheable → 使用
GenericJackson2JsonRedisSerializer简单好用- RedisTemplate 手动操作 → 使用自定义 Jackson2JsonRedisSerializer,灵活可控
- 建议 CacheManager 和 RedisTemplate 序列化器分开配置,避免冲突
6️⃣ 最终 RedisCacheManager 实现(单独修改 Manager,不动 RedisTemplate)
@Bean("redisCacheManager")
public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
// ===== 1. 默认配置 =====
RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1)) // 默认 TTL 1 小时
.serializeKeysWith(
RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
.disableCachingNullValues();
// ===== 2. 按 cacheName 配置不同 TTL =====
Map<String, RedisCacheConfiguration> cacheConfigs = new HashMap<>();
cacheConfigs.put("deviceTypes", defaultConfig.entryTtl(Duration.ofHours(6))); // 静态列表长 TTL
cacheConfigs.put("roleDetails", defaultConfig.entryTtl(Duration.ofHours(12))); // 角色信息
cacheConfigs.put("hotOrders", defaultConfig.entryTtl(Duration.ofMinutes(5))); // 热点业务数据
// ===== 3. 构建 RedisCacheManager =====
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(defaultConfig) // 默认配置
.withInitialCacheConfigurations(cacheConfigs) // 自定义 TTL 配置
.transactionAware() // 事务支持
.build();
}
-
特点:
- 单个 Manager 管理所有缓存
- 按 cacheName 可以单独设置 TTL
- 与 @Cacheable、@CacheEvict 配合直接使用
- 默认 TTL 1 小时,未配置的缓存会使用默认值
- 序列化器使用 GenericJackson2JsonRedisSerializer,和 Spring Cache 默认兼容
7️⃣ @Cacheable 使用示例
@Cacheable(value = "deviceTypes", key = "'all'")
public List<DeviceType> listDeviceTypes() { ... }
@CacheEvict(value = "deviceTypes", allEntries = true)
public void refreshDeviceTypes() { ... }
@Cacheable查询时自动缓存@CacheEvict可主动刷新缓存
8️⃣ 总结
-
RedisTemplate:手动操作 Redis
-
RedisCacheManager:@Cacheable/@CacheEvict 使用,统一管理缓存
-
TTL 管理:默认 + 按 cacheName 配置
-
序列化:
- CacheManager → GenericJackson2JsonRedisSerializer
- RedisTemplate → 自定义 Jackson2JsonRedisSerializer
-
大厂做法:一个 Manager + 多 cacheName,不动 RedisTemplate 配置
这份笔记可以直接用作 Spring Boot Redis 缓存配置参考,支持微服务架构下的业务加速和缓存管理。
如果你需要,我可以帮你画一个 CacheManager + RedisTemplate + @Cacheable 流程示意图,更直观理解缓存流程。
你希望我画吗?