magic-spring-boot-starter-redis 提供了两种优雅的 Redis 缓存使用方式,兼顾灵活性和便捷性:

  • 编程式缓存:基于 Spring Data Redis 框架的 RedisTemplate 操作模板
  • 声明式缓存:基于 Spring Cache 框架的 @Cacheable 注解

关于 SpringCache , 不太了解的同学,可以先阅读:品味 SpringCache 设计之美 (opens new window)

文章视频地址:https://www.bilibili.com/video/BV1ZK411e751

# 1 编程式缓存 Spring Data Redis

技术实现:基于 Spring Data Redis 的 RedisTemplate 操作模板

适用场景:需要精细控制缓存逻辑的复杂业务场景

核心优势

  • 直接操作 Redis 命令,灵活性高
  • 支持原子性操作和复杂数据结构

代码示例:

@Service
public class ProductService {
    @Autowired
    private RedisTemplate<String, Product> redisTemplate;

    public Product getProduct(String sku) {
        // 先查缓存
        Product product = redisTemplate.opsForValue().get("product:" + sku);
        if (product == null) {
            // 缓存未命中时查DB
            product = productRepository.findBySku(sku);
            // 写入缓存并设置TTL
            redisTemplate.opsForValue().set(
                "product:" + sku, 
                product,
                Duration.ofMinutes(30));
        }
        return product;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 2 声明式缓存 SpringCache

技术实现 :基于 Spring Cache 抽象 + @Cacheable 等注解

适用场景 :常规缓存需求,追求代码简洁性

核心优势

  • 无侵入式缓存,业务代码零污染
  • 支持条件缓存(unless/condition)

示例代码 :

// 创建菜单并清理指定权限的缓存
@CacheEvict(
    value = RedisKeyConstants.PERMISSION_MENU_ID_LIST, 
    key = "#createReqVO.permission",
    condition = "#createReqVO.permission != null"  // 仅当permission非空时执行缓存清理
)
public Long createMenu(MenuSaveVO createReqVO) {
    // 数据转换与初始化
    MenuDO menu = BeanUtils.toBean(createReqVO, MenuDO.class);
    initMenuProperty(menu);
    
    // 持久化操作
    menuMapper.insert(menu);
    return menu.getId();
}

// 更新菜单(全量清理缓存)
@CacheEvict(
    value = RedisKeyConstants.PERMISSION_MENU_ID_LIST,
    allEntries = true  // 强制清空整个缓存区域
)
public void updateMenu(MenuSaveVO updateReqVO) {
    // 数据转换与初始化
    MenuDO updateObj = BeanUtils.toBean(updateReqVO, MenuDO.class);
    initMenuProperty(updateObj);
    
    // 持久化操作
    menuMapper.updateById(updateObj);
}

// 根据权限获取菜单ID列表(带缓存读取)
@Cacheable(
    value = RedisKeyConstants.PERMISSION_MENU_ID_LIST,
    key = "#permission"  // 以permission参数作为缓存键
)
public List<Long> getMenuIdListByPermissionFromCache(String permission) {
    // 缓存未命中时的数据加载逻辑
    List<MenuDO> menus = menuMapper.selectListByPermission(permission);
    return convertList(menus, MenuDO::getId);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

创建和修改菜单时会删除所有的菜单缓存 (使用注解 CacheEvict ),而根据权限 permission 查询时,会缓存该权限对应的所有的菜单 ID 列表 (使用注解 Cacheable )。

# 3 基本原理

# 01 Spring Data Redis

Spring Data Redis 是 Spring Data 项目的一部分,它为 Redis 提供了 方便、统一的访问方式,封装了对 Redis 的操作。

Spring Data Redis 底层的连接通信实现是通过 Redis 客户端来完成的,它本身不直接实现 Redis 协议,而是通过整合已有的 Redis Java 客户端

目前支持的主要客户端有三个:

特性 / 客户端 Jedis Lettuce Redisson
类型 原始客户端 原始客户端 高级封装客户端
IO 模型 BIO(阻塞 IO) NIO(基于 Netty) NIO(基于 Netty)
连接复用 每线程独立连接(需连接池) 支持共享连接(多线程复用) 支持共享连接
异步支持 ✅(支持异步 / 响应式) ✅(支持异步)
分布式锁 ❌(需手动实现) ❌(需手动实现) ✅(内置支持)
限流 / 信号量 / 队列 ✅(全面支持)
事务支持
Lua 脚本
Pub/Sub
连接池机制 必须使用(如 JedisPool) 可选(线程安全,无需池) 内部管理
学习成本 中高
Spring Boot 默认支持 ❌(需配置) ✅(默认客户端) ❌(需手动集成)
适合场景 小型、简单应用 中大型系统、响应式、高并发 高并发 + 分布式功能场景

默认情况下,项目中添加依赖 , 依赖的客户端是:Lettuce

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
1
2
3
4

但假如我们想使用 Redisson 的高级功能 (分布式锁、消息队列、限流) ,那么需要添加 Reddisson 的 Spring Data Redis 依赖。

<!-- Redisson 启动器,简化与 Spring Boot 的集成 -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
</dependency>

<!-- Redisson 对 Spring Data Redis 的整合,版本号中的 27 对应 Spring Data 2.7.x -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-data-27</artifactId>
</dependency>
1
2
3
4
5
6
7
8
9
10
11

接下来,配置 RedisTemplate Bean,使用 JSON 序列化方式 。

 /**
     * 创建 RedisTemplate Bean,使用 JSON 序列化方式
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        // 创建 RedisTemplate 对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置 RedisConnection 工厂。😈 它就是实现多种 Java Redis 客户端接入的秘密工厂。感兴趣的胖友,可以自己去撸下。
        template.setConnectionFactory(factory);
        // 使用 String 序列化方式,序列化 KEY 。
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        // 使用 JSON 序列化方式(库是 Jackson ),序列化 VALUE 。
        template.setValueSerializer(buildRedisSerializer());
        template.setHashValueSerializer(buildRedisSerializer());
        return template;
    }

    public static RedisSerializer<?> buildRedisSerializer() {
        RedisSerializer<Object> json = RedisSerializer.json();
        // 解决 LocalDateTime 的序列化
        ObjectMapper objectMapper = (ObjectMapper) ReflectUtil.getFieldValue(json, "mapper");
        objectMapper.registerModules(new JavaTimeModule());
        return json;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

通过上面的配置,我们可以使用 Spring Data Redis 的基础功能 ,同时也可以使用 Redisson 的高级功能。

下面是使用分布式锁的一个例子,我们可以天然使用 Redisson 的内置客户端 RedissonClient

@RestController
@Slf4j
public class DefaultController {

    @Autowired
    private RedissonClient redissonClient;

    @RequestMapping(value = {"/test"})
    @PermitAll
    public CommonResult<Boolean> test(HttpServletRequest request) {
        // 打印查询参数
        Lock lock = redissonClient.getLock("testLock");
        try {
            lock.lock();

            // 省略代码


        }finally {
            lock.unlock();
        }
        return CommonResult.success(true);
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 02 Spring Cache

1、添加依赖

要实现 Spring Cache 的功能,首先添加 Spring Cache 的依赖。

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-cache</artifactId> <!-- 实现对 Caches 的自动化配置 -->
</dependency>
1
2
3
4

2、配置

在 application.yaml 配置文件中,通过 spring.redis 配置项,设置 Redis 的配置。如下图所示:

3、配置 CacheManager

最后,需要用于通过 RedisCacheManagerRedisCacheConfiguration 来自定义 Spring Cache 缓存的行为。

  • RedisCacheConfiguration 定义缓存行为

  • RedisCacheManager 缓存管理器

Spring Cache 默认使用 spring.cache.redis.time-to-live 配置项,设置缓存的过期时间,项目默认为 1 小时。

如果你想自定义过期时间,可以在 @Cacheable 注解中的 cacheNames 属性中,添加 #{过期时间} 后缀,单位是秒。如下图所示:

过期时间

如下图,TimeoutRedisCacheManager 缓存管理器内部创建缓存对象时,会通过 cacheName 属性解析出过期时间参数,并重新设置。

上次更新: 2026/6/28