redisTemplate.opsForValue().get(KEY)从Redis中取出的值为null 的解决方法
最近,博主在整理毕设时就遇到一个问题:我往Redis中存手机验证码,我把手机号当做key ,验证码当做value 存储到 Redis 中,但是在我在需要在登录操作中取验证码时遇到一个问题:
困惑:
@Resource
private RedisTemplate<String,String> redisTemplate;
String phone = user.getPhone();
log.info("当前获取的手机号为:{}",phone);
//从redis中获取手机验证码
String userPhoneKey = redisTemplate.opsForValue().get(phone);
我Redis 中明明存的有,但是就是取不到,显示为null。
我调试了好久,最后在一篇文章中找到了解决方法:
其实问题表象很诡异,但问题的原因很简单,就是Redis中存数据和取数据时采用了不同的RedisTemplate导致的。
我之前的redisTemplate 的注入方法一个写的是:文章来源:https://www.toymoban.com/news/detail-507855.html
一个接口上写的 @Resource
@Resource
private RedisTemplate<String,String> redisTemplate;
一个接口上写的 @Autowired
@Autowired
private RedisTemplate<String,String> redisTemplate;
在SpringBoot中,针对Redis的自动配置类默认会初始化两个RedisTemplate,
初始化了两个RedisTemplate的bean。
第一个Bean类型为RedisTemplate<Object, Object>,Bean的名称为redisTemplate,而且是当容器中不存在对应的Bean name时才会进行初始化。
第二Bean类型为StringRedisTemplate,Bean的名称为stringRedisTemplate,
该类继承自RedisTemplate<String, String>。
**总结:也就说一个Bean是针对Object对象处理的,一个是针对String对象进行处理的**
导致出现坑的原因便是set时注入的是RedisTemplate<Object, Object>,
而获取时注入的是StringRedisTemplate。这么明显的错误应该很容易排查的
如果直接是因为两处类型不一致导致的,的确很好排查,
看一下注入的RedisTemplate即可。但问题难以排查,还因为另外一个因素:
@Resource和@Autowired注入的问题。
**原因:**
采用了@Resource注入方式,如下
@Resource
private RedisTemplate<String, String> redisTemplate;
采用的是@Autowired注入的:
@Autowired
private RedisTemplate<String, String> redisTemplate;
区别:
1:当采用@Autowired时,根据类型注入,直接注入了RedisTemplate<String, String>的bean,
因为它们的类型都是String的。
2:当使用@Resource注入时,默认采用的是根据名称匹配,源码中可以看到
redisTemplate对应的类型为RedisTemplate<Object, Object>。
因此,两处注入了不同的RedisTemplate,于是就导致了获取时获取不到值的问题。
解决方法:文章来源地址https://www.toymoban.com/news/detail-507855.html
解决方法:
方案一,将@Resource的注入改为@Autowired。
方案二:将@Resource注入的bean名称由redisTemplate改为stringRedisTemplate。当然根据具体业务场景还有其他解决方案。
到了这里,关于redisTemplate.opsForValue().get(KEY)从Redis中取出的值为null 的解决方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!