一身报国有万死,双鬓向人无再青。 —— 陆游
封装了一个操作redis的管理层,简单处理了缓存穿透、击穿、雪崩问题
Manager
| package com.ruben.manager;
 import com.alibaba.fastjson.TypeReference;
 
 import java.util.function.Supplier;
 
 
 
 
 
 
 
 public interface RedisManager {
 
 
 
 
 
 
 
 
 
 
 <T> T getFromRedisOrPutIntoMysql(String key, Supplier<T> mysqlSupplier, TypeReference<T> typeReference);
 }
 
 | 
实现类
| package com.ruben.manager;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.TypeReference;
 import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
 import com.ruben.utils.Opt;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.security.SecureRandom;
 import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Supplier;
 
 
 
 
 
 
 
 @Service
 public class RedisManagerImpl implements RedisManager {
 
 public static final SecureRandom SECURE_RANDOM = new SecureRandom();
 
 
 
 public static final int EXPIRE_SECONDS = 5 * 60 * 1000;
 
 @Resource
 private StringRedisTemplate stringRedisTemplate;
 
 
 
 
 
 
 
 
 
 
 
 @Override
 @Transactional(readOnly = true, propagation = Propagation.NOT_SUPPORTED, isolation = Isolation.READ_UNCOMMITTED)
 public <T> T getFromRedisOrPutIntoMysql(String key, Supplier<T> mysqlSupplier, TypeReference<T> typeReference) {
 
 Opt.ofNullable(key).filter(StringUtils::isNotEmpty)
 .orElseThrow(() -> new MybatisPlusException("key不能为空"));
 
 String value = stringRedisTemplate.opsForValue().get(key);
 if (Objects.nonNull(value)) {
 return JSON.parseObject(value, typeReference);
 }
 
 synchronized (this) {
 
 return Opt.ofNullable(mysqlSupplier).map(Supplier::get)
 
 .peek(v -> stringRedisTemplate.opsForValue()
 .set(key, JSON.toJSONString(v), SECURE_RANDOM.nextInt(EXPIRE_SECONDS), TimeUnit.SECONDS))
 
 .orElseGet(() -> {
 stringRedisTemplate.opsForValue()
 .set(key, "{}", SECURE_RANDOM.nextInt(EXPIRE_SECONDS), TimeUnit.SECONDS);
 return null;
 });
 }
 }
 
 }
 
 | 
使用方式
| @Resourceprivate RedisManager redisManager;
 
 @Test
 public void managerTest() {
 List<String> userIds = redisManager.getFromRedisOrPutIntoMysql("userIds", () -> {
 
 return Arrays.asList("1", "2", "3");
 }, new TypeReference<List<String>>() {
 });
 System.out.println(userIds);
 }
 
 | 
目前自己开发中用着感觉还不错的,大伙可以拿去自定义
