redisTemplate.opsForValue().get(KEY)从Redis中取出的值为null 的解决方法

文章讲述了在SpringBoot项目中遇到的一个问题,即使用RedisTemplate从Redis中获取值时返回null。原因是由于在不同地方使用了不同类型的RedisTemplate,一个是RedisTemplate<Object,Object>,另一个是StringRedisTemplate。通过分析@Resource和@Autowired的区别,作者发现名称匹配和类型匹配的差异导致了这个问题。解决方案是统一注入方式或修改bean名称以匹配正确的模板。

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 的注入方法一个写的是

      一个接口上写的 @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,于是就导致了获取时获取不到值的问题。

解决方法:


解决方法:

方案一,将@Resource的注入改为@Autowired。

方案二:将@Resource注入的bean名称由redisTemplate改为stringRedisTemplate。当然根据具体业务场景还有其他解决方案。
06-19
### ARM Assembly `b.ge` Instruction Usage or Equivalent Pseudocode The `b.ge` instruction in ARM assembly is a conditional branch instruction that executes when the condition "greater than or equal" is met. This condition corresponds to the flags being set such that the result of a previous comparison indicates the first operand is greater than or equal to the second operand[^1]. In ARM, this condition relies on the status of the N (negative) and Z (zero) flags after a comparison operation. #### Conditional Flags for `b.ge` - The `b.ge` instruction checks if the signed greater than or equal condition holds true. Specifically: - It branches if the Z flag is set (indicating equality) or if the N flag matches the V (overflow) flag (indicating no overflow occurred during a signed comparison)[^2]. - The equivalent condition code for `b.ge` is `GE`, which stands for "Greater than or Equal" for signed values. #### Example Code Using `b.ge` Below is an example demonstrating the use of the `b.ge` instruction: ```assembly mov r0, #40 @ Load value 40 into register r0 mov r1, #25 @ Load value 25 into register r1 loop: cmp r0, r1 @ Compare r0 with r1 bge end_loop @ Branch to end_loop if r0 >= r1 sub r1, r1, r0 @ Subtract r0 from r1 if r0 < r1 b loop @ Loop back to the start of the loop end_loop: sub r0, r0, r1 @ Subtract r1 from r0 if r0 >= r1 b loop @ Continue looping until r0 == r1 ``` In this example: - The `cmp` instruction compares the values in registers `r0` and `r1`. - The `bge` (branch if greater than or equal) instruction evaluates the condition based on the flags set by the `cmp` instruction. - If the condition is met (`r0 >= r1`), the program branches to the label `end_loop`. #### Equivalent Pseudocode for `b.ge` The following pseudocode represents the logic implemented by the `b.ge` instruction: ```python if (N == V or Z == 1): # N: Negative flag, V: Overflow flag, Z: Zero flag branch_to_label() ``` This pseudocode reflects the underlying mechanism of the `b.ge` instruction, where the branch occurs if the zero flag is set or if the negative and overflow flags are equal, indicating no overflow during a signed comparison[^3]. #### Important Notes on `b.ge` - The `b.ge` instruction operates on signed integers. For unsigned comparisons, the `bhs` (branch if higher or same) instruction should be used instead[^4]. - Before using `b.ge`, a comparison instruction like `cmp` must be executed to set the appropriate condition flags. --- ###
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大怪~将军

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值