今天在使用Spring Cache时,调用@CachePut修饰的方法发现并不能存入redis,且没有任何报错,一番学习后发现,是由于this调用被@Sync @Transactional @Cacheable等注解修饰的方法使得AOP失效,导致无法缓存。
package com.wanjie.ruijitakeout.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.wanjie.ruijitakeout.common.Result; import com.wanjie.ruijitakeout.entity.User; import com.wanjie.ruijitakeout.mapper.UserMapper; import com.wanjie.ruijitakeout.service.UserService; import com.wanjie.ruijitakeout.utils.MailUtils; import com.wanjie.ruijitakeout.utils.ValidateCodeUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import java.util.Map; import java.util.Optional; @Service @RequiredArgsConstructor @Slf4j public class UserServiceImpl extends ServiceImpl解决办法implements UserService { private final MailUtils mailUtils; @CachePut(value = "code", key = "#phone") public String redisSaveCode(String phone, String code) { log.info("缓存验证码,邮箱: {}, 验证码: {}", phone, code); return code; } @CacheEvict(value = "code", key = "#phone") public void redisDeleteCode(String phone, String code) { log.info("删除缓存验证码,邮箱: {}, 验证码: {}", phone, code); } @Cacheable(value = "code", key = "#phone") public String redisGetCode(String phone) { log.info("获取验证码,邮箱: {}", phone); return null; } @Override public Result sendMsg(User user, HttpServletRequest request) { // 获取手机号 String phone = user.getPhone(); if (!StringUtils.isEmpty(phone)) { // 生成4位验证码 String code = ValidateCodeUtils.generateValidateCode(4).toString(); log.info("验证码: {}", code); // 发送邮箱 mailUtils.sendMail(phone, code); // 将验证码存储到 redis中 有效期 3 分钟 //redisTemplate.opsForValue().set(phone, code, 5, TimeUnit.MINUTES); redisSaveCode(phone, code); return Result.success(code, null); //正常调用,但并没有缓存,即注解没有生效 } return Result.fail("非法手机号"); } }
- 注入ApplicationContext
- 使用 applicationContext.getBean(UserServiceImpl.class).redisSaveCode(phone,code);来取代this调用
- https://blog.csdn.net/z69183787/article/details/113888646



