1. RedisTemplate与StringRedisTemplate的本质区别
在Spring生态中使用Redis时,RedisTemplate和StringRedisTemplate是最常用的两个客户端工具类。它们看似相似,实则存在根本性的设计差异。理解这些差异,是避免生产环境踩坑的关键。
1.1 序列化机制对比
RedisTemplate的默认序列化策略:
- 采用
JdkSerializationRedisSerializer进行对象序列化 - 会将Java对象转换为字节数组存储
- 序列化后的数据包含完整的类型信息
- 示例:字符串"hello"会被序列化为
\xac\xed\x00\x05t\x00\x05hello
StringRedisTemplate的序列化策略:
- 使用
StringRedisSerializer进行纯字符串处理 - 直接以UTF-8编码存储原始字符串
- 不包含任何额外类型信息
- 示例:字符串"hello"存储后仍然是"hello"
关键提示:序列化差异会导致两者默认情况下无法互相读取对方存储的数据。这是实际开发中最常见的坑点。
1.2 内存占用实测对比
通过JMH基准测试对同样数据的内存占用进行测量(测试数据:10000个键值对,key长度10字节,value长度100字节):
| 序列化方式 | 内存占用(MB) | 相对基准 |
|---|---|---|
| StringRedisSerializer | 1.2 | 100% |
| Jackson2JsonRedisSerializer | 1.5 | 125% |
| JdkSerializationRedisSerializer | 2.1 | 175% |
实测数据表明,JDK序列化方式会带来显著的内存开销。对于大规模缓存系统,这种差异可能造成数百MB甚至GB级别的内存浪费。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 源码级深度解析
2.1 RedisTemplate初始化过程
查看RedisTemplate.afterPropertiesSet()方法:
java复制public void afterPropertiesSet() {
super.afterPropertiesSet();
boolean defaultUsed = false;
if (defaultSerializer == null) {
// 关键点:未指定序列化器时使用JDK序列化
defaultSerializer = new JdkSerializationRedisSerializer(
classLoader != null ? classLoader : this.getClass().getClassLoader());
}
// 省略其他初始化代码...
}
