Spring Boot 中 StringRedisTemplate 与 RedisTemplate 的区别与使用陷阱(附 getBean 为何报错

🌟 引言

在 Spring Boot 项目中操作 Redis,我们最常用的两个类就是:

  • StringRedisTemplate
  • RedisTemplate

但你是否遇到过这些问题?

  • 为什么我存进去的对象在 Redis 里是乱码?
  • 为什么 SpringUtil.getBean(RedisTemplate.class) 报错"找到两个 Bean"?
  • 到底该用哪个?它们有什么区别?

本文将带你彻底搞懂这两个类的 核心区别、适用场景 ,并解释那个让人头疼的 getBean 报错原因!


一、核心区别:一句话总结

类型 StringRedisTemplate RedisTemplate
用途 专门操作字符串 通用模板,可操作对象
Key/Value 序列化 StringRedisSerializer(UTF-8) JdkSerializationRedisSerializer(二进制)
Redis 中是否可读 ✅ 是(明文) ❌ 否(乱码)
是否支持 Java 对象 ❌ 不推荐 ✅ 是(需自定义序列化)

简单说

  • StringRedisTemplate:存字符串,明文可读,推荐日常使用。
  • RedisTemplate:存对象,但默认是乱码,需优化。

二、序列化方式详解

1. StringRedisTemplate:明文存储

复制代码
@Autowired
private StringRedisTemplate stringRedisTemplate;

// 存储
stringRedisTemplate.opsForValue().set("user:name", "张三");

✅ 在 Redis 中查看:

复制代码
"user:name" -> "张三"

👉 明文可读,调试方便


2. RedisTemplate:默认乱码

复制代码
@Autowired
private RedisTemplate redisTemplate;

User user = new User(1, "张三");
redisTemplate.opsForValue().set("user:1", user);

❌ 在 Redis 中查看:

复制代码
"\xac\xed\x00\x05t\x00\x08user:1" -> "\xac\xed\x00\x05sr\x00..."

👉 全是乱码!因为使用了 JDK 序列化


✅ 如何让 RedisTemplate 也存明文?

自定义配置,使用 JSON 序列化

复制代码
@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        // Key 用 String 序列化
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());

        // Value 用 JSON 序列化(推荐!)
        Jackson2JsonRedisSerializer<Object> serializer = 
            new Jackson2JsonRedisSerializer<>(Object.class);
        template.setValueSerializer(serializer);
        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();
        return template;
    }
}

这样存进去的就是 JSON 字符串了:

复制代码
"user:1" -> {"id":1,"name":"张三"}

✅ 可读!✅ 易调试!


三、SpringUtil.getBean(RedisTemplate.class) 为什么报错?

你可能写过这样的工具类:

复制代码
public class SpringUtil {
    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }
}

然后调用:

复制代码
RedisTemplate template = SpringUtil.getBean(RedisTemplate.class);

结果报错:

复制代码
No qualifying bean of type 'RedisTemplate' available: 
expected single matching bean but found 2

❓ 为什么会找到两个 Bean?

因为:

  1. 你自定义了一个 RedisTemplate Bean(比如叫 redisTemplate
  2. 你还有一个 StringRedisTemplate Bean(名字是 stringRedisTemplate

StringRedisTemplate 的源码是:

复制代码
public class StringRedisTemplate extends RedisTemplate<String, String>

👉 它 继承自 RedisTemplate

所以当你用:

复制代码
getBean(RedisTemplate.class)

Spring 会查找所有 类型为 RedisTemplate 或其子类 的 Bean,于是找到了:

  • redisTemplate(你自定义的)
  • stringRedisTemplateStringRedisTemplate 实例)

❌ 找到两个,Spring 不知道选哪个,于是报错!


✅ 正确获取方式(推荐)

方案 1:通过名称获取(最安全)

复制代码
// 获取自定义 RedisTemplate
RedisTemplate template = (RedisTemplate) SpringUtil.getBean("redisTemplate");

// 获取 StringRedisTemplate
StringRedisTemplate strTemplate = (StringRedisTemplate) SpringUtil.getBean("stringRedisTemplate");

方案 2:直接用 StringRedisTemplate.class(唯一)

复制代码
// ✅ 这个可以唯一匹配,不会冲突
StringRedisTemplate template = SpringUtil.getBean(StringRedisTemplate.class);

方案 3:使用 @Qualifier 注解

复制代码
@Autowired
@Qualifier("redisTemplate")  // 明确指定
private RedisTemplate redisTemplate;

四、什么时候用哪个?(适用场景)

场景 推荐使用
存字符串、数字、JSON 字符串 StringRedisTemplate
存简单键值对(如 token、配置) StringRedisTemplate
存 Java 对象且希望可读 RedisTemplate + JSON 序列化
防止缓存穿透(存空值) StringRedisTemplate(可存 """null"
多数据源、复杂场景 ✅ 自定义多个 RedisTemplate,用名称区分

✅ 最佳实践建议

  1. 90% 场景下,优先使用 StringRedisTemplate
  2. ✅ 把对象转成 JSON 字符串再存:JSON.toJSONString(user)
  3. ✅ 避免使用 getBean(RedisTemplate.class),改用名称或 StringRedisTemplate.class
  4. ✅ 如果要用 RedisTemplate,务必配置 JSON 序列化

💬 结语

StringRedisTemplateRedisTemplate 看似相似,实则大有不同。理解它们的 序列化机制继承关系,能帮你避免很多"Redis 乱码"、"getBean 找到多个"等经典坑。

📌 记住

  • 想简单?用 StringRedisTemplate
  • 想存对象?用 RedisTemplate + JSON 序列化
  • 想安全?用 getBean("beanName")getBean(StringRedisTemplate.class)

如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、转发!也欢迎在评论区分享你的 Redis 使用经验 👇

相关推荐
计算机毕业设计小帅12 小时前
【2026计算机毕业设计】基于Springboot的Android校园周边美食汇系统
android·spring boot·课程设计
Terio_my13 小时前
Java bean 数据校验
java·开发语言·python
Tony Bai13 小时前
【Go开发者的数据库设计之道】07 诊断篇:SQL 性能诊断与问题排查
开发语言·数据库·后端·sql·golang
超级大只老咪13 小时前
何为“类”?(Java基础语法)
java·开发语言·前端
花花鱼14 小时前
spring boot项目使用tomcat发布,也可以使用Undertow(理论)
spring boot·后端·tomcat
我笑了OvO14 小时前
C++类和对象(1)
java·开发语言·c++·类和对象
weixin_4365250715 小时前
Gitee - IDEA 主支 master 和分支 dev 的使用
java·ide·intellij-idea
你的人类朋友16 小时前
快速搭建redis环境并使用redis客户端进行连接测试
前端·redis·后端
sheji341616 小时前
【开题答辩全过程】以 YF精品视频动漫平台为例,包含答辩的问题和答案
java·eclipse
小蕾Java16 小时前
Java 开发工具,最新2025 IDEA 使用
java·ide·intellij-idea