Redisson RMap获取自定义MyCache对象为空问题求助
问题原因及解决办法
1. 泛型类型丢失导致反序列化失败
你在使用MyCache时采用了原始类型(未指定泛型参数T),Redisson在序列化泛型对象时需要明确的类型信息。存入原始类型的MyCache后,反序列化阶段无法正确识别valueMap中的元素类型,最终导致集合内容丢失。
解决方式:
使用带具体泛型参数的类型声明,同时在获取RMap时指定完整泛型:
// 存入时 RMap<String, MyCache<Company>> cacheMap = Redisson.create(redissonConfig).getMap("my-redis-stack"); MyCache<Company> myCache = new MyCache<>(); myCache.getValueMap().put("MC", company); cacheMap.fastPut("myCompanies", myCache); // 取出时 RMap<String, MyCache<Company>> cacheMap = Redisson.create(redissonConfig).getMap("my-redis-stack"); MyCache<Company> result = cacheMap.get("myCompanies");
2. Final字段的序列化兼容性问题
MyCache中的三个集合字段均为final且直接在声明时初始化,Java默认序列化机制对这类字段的处理存在局限性——反序列化时可能会重新初始化这些集合(生成空的新集合),导致原有数据丢失。
解决方式:
- 方案一:自定义序列化/反序列化方法,手动处理集合内容:
public class MyCache<T> implements Serializable { protected final Map<String, T> valueMap = new HashMap<>(); private final Set<CacheEventListener> cacheEventListeners = new HashSet<>(); protected final Map<String, Integer> cacheMinutesMap = new HashMap<>(); // getters and setters private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ois.defaultReadObject(); // 手动恢复集合数据 valueMap.putAll((Map<String, T>) ois.readObject()); cacheEventListeners.addAll((Set<CacheEventListener>) ois.readObject()); cacheMinutesMap.putAll((Map<String, Integer>) ois.readObject()); } private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); // 手动写入集合数据 oos.writeObject(valueMap); oos.writeObject(cacheEventListeners); oos.writeObject(cacheMinutesMap); } }
- 方案二:切换为Redisson的
JsonJacksonCodec序列化方式,JSON序列化对final字段的兼容性更好:
Config redissonConfig = Config.fromYAML(new File(configPath)); // 设置全局JSON序列化器 redissonConfig.setCodec(new JsonJacksonCodec()); RMap<String, MyCache<Company>> cacheMap = Redisson.create(redissonConfig).getMap("my-redis-stack");
3. CacheEventListener未实现Serializable
如果CacheEventListener接口的实现类没有实现Serializable接口,MyCache在序列化时会触发NotSerializableException,若Redisson吞掉该异常,会导致存入的对象不完整,取出后为空。
解决方式:
确保CacheEventListener的所有实现类都实现Serializable接口:
public interface CacheEventListener extends Serializable { // 接口方法 }
内容的提问来源于stack exchange,提问作者psa
相关产品推荐
相关产品推荐

