1、缓存穿透: 要重视,尤其是@Cacheable、返回值可能为null的场景下
import org.springframework.cache.interceptor.CacheAspectSupport;
import org.springframework.cache.interceptor.CacheOperationInvoker;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
/**
* Optional包装工具类,代替@Cacheable场景下的Optional来使用
* <p>
* {@link org.springframework.cache.interceptor.CacheAspectSupport#execute(CacheOperationInvoker, Method, CacheAspectSupport.CacheOperationContexts)}
* <p>
* 因为spring-cache不支持Optional.EMPTY, 在将Optional对象set入cache时, 会做拆包
* cacheValue = this.unwrapReturnValue(returnValue)
* 进而导致从cache中get时,无法区分以下两种情况(为null默认缓存未命中,框架的逻辑,无法绕过):
* 1、key存在,value为null
* 2、key不存在
* 进而导致Optional.EMPTY也无法绕过,引发缓存穿透问题,故写此工具类,代替Optional
* <p>
* 其次,Optional没有implements Serializable,因此无法使用JDK序列化放入redis
* <p>
* {@link com.company.ec.cache.redis.RedisClient#put(String, Object, int)} byte[] values = SerializeUtils.serialize(value);
* <p>
*/
public final class OptionalWrapUtil<T> implements Serializable