不知道大家在使用redis的時候,有沒有遇到過如下錯誤:java.lang.ClassNotFoundException,這個錯誤是因爲反序列化時找不到對應的對象導致的。
什麼是序列化
在開始今天的課程之前,我們先來介紹一下:什麼是redis的系列化和反序列化。
數據想要存入redis緩存之前,需要序列化爲byte數組,從redis中取出數據,卻是一個相反的過程,需要將byte數組反序列纔可以。
刨根問題
介紹完序列化和反序列化之後,我們繼續回到剛纔的問題,爲什麼會發生ava.lang.ClassNotFoundException錯誤呢?
這個問題本質是因爲序列化和反序列化不對稱引起的,那什麼情況下會發生這種問題呢?發生這種問題又需要如何解決呢?
問題誘因
導致java.lang.ClassNotFoundException問題有:
- 序列化和反序列化的serialVersionUID不一致。
- 反序列的對象和反序列化的對象所屬的包名不一致。
處理方案
出現java.lang.ClassNotFoundException錯誤無非就是上面所說的兩種問題,第一種好解決,只要在類上面加上如下所示的代碼即可。
private static final long serialVersionUID = -5172532647273106745L;
序列化和反序列化的對象的ID需要一致(一個數字都不能錯)
第二個問題引起的反序列化問題,有兩種解決方案。序列化和反序列化的對象包命一致即可,但是有時候修改包命並不現實,可能代價會非常高,這個時候我們可以通過如下所示的代碼,在序列化之前進行包命的替換。
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
String name = desc.getName();
try {
if (name.startsWith("com.fourkmiles.monitor")) {
// 監控項目包命替換
name = name.replace("com.fourkmiles.monitor.model.po", "com.fourkmiles.batch.model.po.monitor");
}
return Class.forName(name);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return super.resolveClass(desc);
}
通過如上所示的代碼就可以不用修改包命的情況下,反序列化成功。
總結
我們在使用redis的時候,一定要去了解redis核心部分的相關原理,這樣在出現問題的時候,我們也可以快速的定位問題發生的原因,並快速解決。
後記
- redis中list結構類型的數據,存在多種序列化不同的相同對象,這個時候要如何進行反序列化?
- redis內存溢出之後,會發生什麼問題?
- 插入redis緩存的數據過大,要如何進行優化?
想要更多幹貨、技術猛料的孩子,快點拿起手機掃碼關注我,我在這裏等你哦~
林老師帶你學編程:https://wolzq.com