在做一个自定义注解来实现分布式锁问题时,发现当走入缓存穿透策略时,每次都报错java.lang.ClassCastException: java.lang.Object; cannot be cast to xxx,
if (object==null){
// 防止缓存穿透
Object object1 = new Object();
redisTemplate.opsForValue().set(key, JSON.toJSONString(object1),RedisConst.SKUKEY_TEMPORARY_TIMEOUT,TimeUnit.SECONDS);
// 返回数据
return object1;
}
于是,我选择了debug模式。可用来debug模式后,报错提示分布式锁删除失败,由于线程id不同。后来发现是因为debug时间太长,导致锁已经过过期时间,导致自动释放,才导致了删锁的失败。
后来根据代码提示找到该段代码,类转换异常应该是从这里来的。
@Override
@GmallCache(prefix = RedisConst.SKUKEY_PREFIX)
public SkuInfo getSkuInfo(Long skuId) {
return getSkuInfoDB(skuId);
}
经过思考,我觉得应该是Object创建时出现的问题,于是我选择用joinpoint获取MethodSignature对象,通过调用他的getReturnType()方法,获得返回值的Class对象,接着调用它的无参构造来生成一个对象进行返回,具体代码如下所示
if (null == object){
//通过分布式锁调用无参构造
Class returnType = signature.getReturnType();
Object o = returnType.getConstructor().newInstance();
redisTemplate.opsForValue().set(key, JSON.toJSONString(o),
RedisConst.SKUKEY_TEMPORARY_TIMEOUT,TimeUnit.SECONDS);
return o;
}
最后运行,问题成功解决!!