在日常开发中,Redis 几乎成了我们提升系统性能的“标配”。缓存热点数据、分布式锁、限流……样样不落。
但随着项目越来越复杂,直接在业务代码中调用 StringRedisTemplate 会让代码变得又臭又长,难以维护。

所以,我们需要一个“高内聚、低耦合”的 Redis 工具类,来解耦 Redis 操作。

今天这篇文章,我们就一起来封装一个通用的 Redis 工具类,并聊聊其中的设计思路。


🧱项目背景

我们使用 Spring Boot 框架,Redis 客户端是 Spring 提供的 StringRedisTemplate,序列化和反序列化用的是 Hutool 工具包(你也可以换成 Jackson / FastJSON / Gson)。

最终的效果是:

// 存对象
cacheUtils.add("user:1001", new User("张三", 18));

// 获取对象
User user = cacheUtils.getObject("user:1001", User.class);

是不是比直接操作 Redis 更清爽?


🔧工具类源码详解

我们先来看代码,再逐段解析思路。

@Slf4j
@Component
public class CacheUtils {

    @Autowired(required = false)
    StringRedisTemplate redisTemplate;

    final String DEFAULT_KEY_PREFIX = "";
    final int EXPIRE_TIME = 6;
    final TimeUnit EXPIRE_TIME_TYPE = TimeUnit.HOURS;

✅ 说明:

  • 使用了 @Component 注解,Spring 会自动注入。
  • 通过 @Autowired(required = false) 注入 RedisTemplate(防止 Redis 没配置时启动报错)。
  • 设置了默认的 key 前缀(用于统一管理缓存命名空间)。
  • 设置了默认的过期时间为 6 小时(可在方法中自定义覆盖)。

1️⃣ 添加缓存

public <K,V> void add(K key, V value) {
    try {
        if (value != null) {
            redisTemplate.opsForValue().set(DEFAULT_KEY_PREFIX + key,
                JSONUtil.toJsonStr(value), EXPIRE_TIME, EXPIRE_TIME_TYPE);
        }
    } catch (Exception e) {
        log.debug(e.getMessage(), e);
        throw new RuntimeException("数据缓存至redis失败");
    }
}

你也可以自定义过期时间:

public <K,V> void add(K key, V value, Integer expireTime, TimeUnit timeUnit) {
    try {
        if (value != null) {
            redisTemplate.opsForValue().set(DEFAULT_KEY_PREFIX + key,
                JSONUtil.toJsonStr(value), expireTime, timeUnit);
        }
    } catch (Exception e) {
        log.debug(e.getMessage(), e);
        throw new RuntimeException("数据缓存至redis失败");
    }
}

🎯 亮点

  • 泛型 <K, V> 支持任意 key 和 value 类型。
  • 通过 JSONUtil.toJsonStr() 实现对象转 JSON 存储。
  • 提供了默认过期时间和自定义过期时间两个方法,灵活性满分。

2️⃣ 获取缓存(字符串形式)

public <K> String get(K key){
    String value = null;
    try{
        value = redisTemplate.opsForValue().get(DEFAULT_KEY_PREFIX + key);
        if("null".equals(value)) {
            return null;
        }
    } catch (Exception e) {
        log.debug(e.getMessage(), e);
    }
    return value;
}

3️⃣ 获取缓存(对象反序列化)

public <K, V> V getObject(K key, Class<V> clazz) {
    String value = this.get(key);
    V result = null;
    if (!StringUtils.isEmpty(value)) {
        result = JSONUtil.toBean(value, clazz);
    }
    return result;
}

🎯 亮点

  • getObject 方法封装了取值 + 反序列化两个步骤。
  • 避免业务层写重复代码,代码更清晰简洁。

💡优化建议

虽然当前这个工具类已经能应付日常开发了,但还是有一些可以进一步优化的地方:

✅ 添加方法泛型增强

目前 add 方法没有返回值,我们可以考虑返回 boolean 表示是否写入成功。

✅ key 统一前缀命名空间

建议将 DEFAULT_KEY_PREFIX 设置为项目级前缀,例如 "pzforest:",避免 Redis 污染。

final String DEFAULT_KEY_PREFIX = "pzforest:";

✅ 添加删除缓存方法

public <K> void delete(K key) {
    redisTemplate.delete(DEFAULT_KEY_PREFIX + key);
}

🧪实战演示

// 写入用户信息到缓存
User user = new User("张三", 18);
cacheUtils.add("user:1001", user, 2, TimeUnit.HOURS);

// 读取用户信息
User cachedUser = cacheUtils.getObject("user:1001", User.class);
System.out.println(cachedUser.getName()); // 张三

🧠写在最后

封装 Redis 工具类的目的,就是让“缓存”这种横切逻辑和业务代码解耦,让我们关注业务本身。
你可以根据项目需求,继续封装更多操作,比如:

  • 缓存空值防击穿
  • 分布式锁(基于 setnx)
  • 缓存预热、延迟双删

希望这篇文章对你有帮助,欢迎点赞、收藏、评论交流!


👨‍💻 作者:一个爱封装工具类的程序员

📬 欢迎关注我,带你写出优雅的 Java 后端代码!


如果你希望我也帮你写文章中的代码注释、文档或 JavaDoc,随时告诉我!

最后修改:2025 年 04 月 13 日
如果觉得我的文章对你有用,请随意赞赏