尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

redis实现缓存3-封装redis工具类

redis实现缓存3-封装redis工具类
📅 发布时间:2026/6/19 22:52:43

image

具体实现:

CacheClient

package com.hmdp.utils;import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import java.time.LocalDateTime;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;import static com.hmdp.utils.RedisConstants.*;@Slf4j
@Component
public class CacheClient {private final StringRedisTemplate stringRedisTemplate;public CacheClient(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate = stringRedisTemplate;}public void set(String key, Object value,Long time, TimeUnit unit) {stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(value), time, unit);}public void setWithLogicalExpire(String key, Object value,Long time, TimeUnit unit) {// 设置逻辑过期RedisData redisData = new RedisData();redisData.setData(value);redisData.setExpireTime(LocalDateTime.now().plusSeconds(unit.toSeconds(time)));// 写入redisstringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(redisData));}public <R,ID> R queryWithPassThrough(String keyPrefix, ID id, Class<R> type, Function<ID,R> dbFallback,Long time, TimeUnit unit){// 1.从redis中查询商铺缓存String key = keyPrefix + id;String json = stringRedisTemplate.opsForValue().get(key);// 2.判断是否存在if(StrUtil.isNotBlank(json)){// 3.存在,直接返回return JSONUtil.toBean(json, type);}// 判断命中的是否是空值if(json != null){return null;}// 4.不存在,根据id查询数据库R r = dbFallback.apply(id);// 5.不存在,返回错误if(r == null){//将空值写入reidsstringRedisTemplate.opsForValue().set(key, "",CACHE_NULL_TTL, TimeUnit.MINUTES);return null;}// 6.存在,写入redisthis.set(key, r, time, unit);// 7.返回return r;}private static final ExecutorService CACHE_REBUILD_EXECUTOR = Executors.newFixedThreadPool(10);public <R,ID> R queryWithLogicalExpire(String keyPrefix,ID id,Class<R> type,Function<ID,R> dbFallback,Long time, TimeUnit unit){// 1.从redis中查询商铺缓存String key = keyPrefix + id;String json = stringRedisTemplate.opsForValue().get(key);// 2.判断是否存在if(StrUtil.isBlank(json)){// 3.存在,直接返回return null;}// 4.命中,把json反序列化为对象RedisData redisData = JSONUtil.toBean(json, RedisData.class);R r = JSONUtil.toBean((JSONObject) redisData.getData(), type);LocalDateTime expireTime = redisData.getExpireTime();// 5.判断是否过期if(expireTime.isAfter(LocalDateTime.now())){// 5.1未过期,直接返回店铺信息return r;}// 5.2过期,要缓存重建// 6.重建缓存// 6.1获取互斥锁String lockKey = LOCK_SHOP_KEY +id;boolean isLock = tryLock(lockKey);// 6.2 判断是否获取锁成功if(isLock){// 6.3 成功,开启独立线程CACHE_REBUILD_EXECUTOR.submit(()->{try {// 查询数据库R r1 = dbFallback.apply(id);// 写入redisthis.setWithLogicalExpire(key, r1, time, unit);} catch (Exception e) {throw new RuntimeException(e);} finally {//释放锁unlock(lockKey);}});}// 6.4 返回过期的店铺信息return r;}private boolean tryLock(String key){Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 10, TimeUnit.SECONDS);return BooleanUtil.isTrue(flag);}private void unlock(String key){stringRedisTemplate.delete(key);}
}

调用工具类:

    @Overridepublic Result queryById(Long id) {// 逻辑过期解决缓存击穿Shop shop = cacheClient.queryWithLogicalExpire(CACHE_SHOP_KEY,id,Shop.class,this::getById,20L,TimeUnit.SECONDS);// 缓存穿透// Shop shop = cacheClient.queryWithPassThrough(CACHE_SHOP_KEY,id,Shop.class,this::getById,CACHE_SHOP_TTL,TimeUnit.MINUTES);// 互斥锁解决缓存击穿// Shop shop = queryWithMutex(id);if (shop == null) {return Result.fail("店铺不存在!");}// 7.返回return Result.ok(shop);}

相关新闻

  • 高阻态
  • ORA-01555系列:二、ORA-01555的场景分析与解决方案
  • Rcc_APBPeriphClockCmd()

最新新闻

  • 2026昆山建筑修缮行业全景分析:昆山鼎壹万防水补漏公司及本地适配服务商深度指南 专业防水公司排名推荐(2026年6月防水补漏最新TOP权威排名) - 鼎壹万修缮说
  • 六安7年烘焙老店|三个叔叔手工吐司文庙街店:用心做好每一款生日蛋糕 - 速递信息
  • 2026合肥防水补漏权威指南:卫生间/屋面/外墙/地下室正规施工+透明报价+避坑全攻略 - 苏易修缮
  • 爱回收买iPad靠谱吗?质检与售后逐项看 - 新闻快传
  • 二手平台哪个更靠谱?从质检、价格到隐私,一份不踩坑的选择框架 - 新闻快传
  • 抢占AI搜索新入口:杭州爱搜索GEO的AI搜索优化实战方法论与标杆案例解析 - 品牌报告

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号