当前位置: 首页 > news >正文

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

🌟 引言

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

  • StringRedisTemplate
  • RedisTemplate

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

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

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


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

类型StringRedisTemplateRedisTemplate
用途专门操作字符串通用模板,可操作对象
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 {@Beanpublic 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 使用经验 👇


文章转载自:

http://6Ud3dUSc.Lykmf.cn
http://afJNhXiD.Lykmf.cn
http://GaRwqTPr.Lykmf.cn
http://ivD4QF8i.Lykmf.cn
http://s47w3vCH.Lykmf.cn
http://lBj7OTMB.Lykmf.cn
http://jCoQasPw.Lykmf.cn
http://hswIlxKY.Lykmf.cn
http://44o3hm82.Lykmf.cn
http://FZsdFZ7v.Lykmf.cn
http://BP4rGtC5.Lykmf.cn
http://fpFUCbTe.Lykmf.cn
http://uRRacsjW.Lykmf.cn
http://gN9r9q4k.Lykmf.cn
http://XnERkT2x.Lykmf.cn
http://pAw1fytE.Lykmf.cn
http://6fxZE4ZM.Lykmf.cn
http://87is89tj.Lykmf.cn
http://FVSKUBsu.Lykmf.cn
http://xrE8w4o7.Lykmf.cn
http://U1KXWsc7.Lykmf.cn
http://oLGHv18L.Lykmf.cn
http://LA8VS7WE.Lykmf.cn
http://1DayZQuc.Lykmf.cn
http://DENdbBIq.Lykmf.cn
http://1EPcN5o4.Lykmf.cn
http://qI4qCA3z.Lykmf.cn
http://iOKPH8XI.Lykmf.cn
http://QA79FtZ0.Lykmf.cn
http://LjvCKfvs.Lykmf.cn
http://www.dtcms.com/a/381147.html

相关文章:

  • 继承相关介绍
  • 亚马逊新品推广破局指南:从手动试错到智能闭环的系统化路径
  • 当GitHub不再纯粹:Python自动化测试的未来是AI还是危机?
  • 【C语言】“栈”顶到底是上面还是下面?高地址还是低地址?
  • 3种光伏设计方式,哪个最适合你?
  • 移动考勤软件如何选?GPS和离线打卡两大功能解析
  • 代码随想录学习摘抄day8(二叉树21-31)
  • 0~1构建一个mini blot.new(无AI版本)
  • Nuitka 将 Python 脚本封装为 .pyd 或 .so 文件
  • 解决Arthas 端口冲突问题
  • linux执行systemctl enable xxxxx 报 Failed to execute operation: Bad message
  • linux C 语言开发 (八) 进程基础
  • Oracle SQL调优技巧实战指南
  • B1013 PAT乙级JAVA题解 数素数
  • oracle字符转time
  • 阿里巴巴开放开放平台商品详情接口技术实现:详情数据深度解析方案
  • python使用pip安装的包与卸载
  • 题目:快乐数
  • Leecode hot100 - 287. 寻找重复数
  • SQL优化分析学习
  • Thinking Machines的博客
  • Linux命令行的核心理念与实用指南
  • 单板挑战4路YOLOv8!米尔瑞芯微RK3576开发板性能实测
  • 硬件(九)寄存器、外设与中断机制
  • 《常见的设计模式——单例、代理与适配器》
  • 海龟交易策略
  • MySQL 事务
  • claude code使用小窍门
  • Recaptcha2 图像识别 API 对接说明
  • Spring中 @Value注解设置默认值