摘要:就是默認(rèn)的序列化器和反序列化器。最后,那為什么會(huì)到這一步呢發(fā)現(xiàn)拿到反序列化器后會(huì)執(zhí)行一個(gè)操作基本上就到這里了,最主要的原因還是方法,并不是很多博文說(shuō)的。
????首先交代背景,前幾天遇到一個(gè)小bug,由于其他系統(tǒng)的一個(gè)DTO子類和父類有一個(gè)字段名重復(fù)了,所以導(dǎo)致我set的子類字段那邊拿不到值。改起來(lái)很簡(jiǎn)單嘛,讓對(duì)面把子類的字段刪掉就好,但是拿不到值的原因讓我想了很久,很明顯是序列化和反序列化的過(guò)程中這個(gè)字段的值丟失了,但是到底是在哪一步呢?還是決定看看源碼給自己一個(gè)答案。
dubbo版本:2.6.7首先先確定協(xié)議和序列化的方式:
ok,dubbo協(xié)議,沒(méi)有配序列化方式,那再來(lái)找一下dubbo默認(rèn)的序列化方式:
首先找到了這個(gè)包:
然后在Serialization接口(實(shí)現(xiàn)一些自定義序列化擴(kuò)展用的)中發(fā)現(xiàn)了默認(rèn)序列化的方式是hessian2
然后通過(guò)Hessian2Serialization的serialize方法和deserialize方法找到了Hessian2ObjectOutput、Hessian2ObjectInput這個(gè)兩個(gè)類,之后通過(guò)里面的writeObject方法和readObject方法,找到了這兩個(gè)類:JavaSerializer和JavaDeserializer。就是默認(rèn)的序列化器和反序列化器。
首先我們來(lái)看序列化:
構(gòu)造方法:
我們看看他干了個(gè)什么事
首先檢查了有沒(méi)有writeReplace方法
然后把所有聲明的字段放到數(shù)組中遍歷,然后把除了transient和static修飾的字段放到ArrayList中去
然后往上找父類執(zhí)行相同操作
然后把所有符合條件的字段放到一個(gè)Field數(shù)組里面,先放基本數(shù)據(jù)類型,再放引用數(shù)據(jù)類型
最后把字段放入對(duì)應(yīng)類型的序列化器中去
得到一個(gè)FieldSerializer序列化器數(shù)組
我們還是繼續(xù)看writeObject方法
主要是第二張圖的3個(gè)方法,做的事情大概就是循環(huán)序列化field的名和值
下面再來(lái)看看反序列化:
構(gòu)造方法:
這里大概做了3個(gè)事
獲取fieldMap,方法如下:
獲取readResolve方法
獲取所有構(gòu)造器
遍歷構(gòu)造器數(shù)組找到cost最小的最佳構(gòu)造器
然后用最佳構(gòu)造器進(jìn)行構(gòu)造,方法如下:
先看構(gòu)造器方法,基本數(shù)據(jù)類型的話返回包裝類型,引用數(shù)據(jù)類型返回null
主要我們來(lái)看獲取fieldMap的時(shí)候。和序列化時(shí)相同,先取子類再取父類,本來(lái)以為到這就結(jié)束了,可是看到了一行校驗(yàn)
fieldMap.get(field.getName()) == null
如果父類的字段名和子類字段名相同,會(huì)跳過(guò)該循環(huán),也就是說(shuō)只會(huì)有子類的值,那為什么還會(huì)覆蓋?
看最后一個(gè)readMap方法:
debug發(fā)現(xiàn)值被覆蓋就是在這里操作的
deser.deserialize(in, obj);
子類set過(guò)值以后,父類過(guò)來(lái)也會(huì)拿到子類的反序列化器,把子類的值覆蓋掉。
最后,那為什么會(huì)到readMap這一步呢?
debug發(fā)現(xiàn)SerializerFactory拿到反序列化器后會(huì)執(zhí)行一個(gè)readMap操作
基本上就到這里了,最主要的原因還是readMap方法,并不是很多博文說(shuō)的fieldMap。如果哪里有不對(duì)的地方歡迎指出、討論以便及時(shí)修改。
參考文檔:鏈接描述
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/76565.html
摘要:使用的序列化是的,而對(duì)于類的反序列化的源碼如下這里我們可以清楚地看出來(lái),將讀取到的轉(zhuǎn)為然后調(diào)用了方法,那么如果我們的屬性為空,那么調(diào)用函數(shù)必然會(huì)拋異常,也就產(chǎn)生了之后的結(jié)果。補(bǔ)充說(shuō)明我找到的源碼可以看出,對(duì)于,,的反序列化均有問(wèn)題存在。 背景 這是我之前提的問(wèn)題:?jiǎn)栴}鏈接 在使用dubbo 2.5.3的時(shí)候,定義的接口中有一個(gè)方法使用了實(shí)體類作為參數(shù),而這個(gè)實(shí)體類中定義了一個(gè)變量為ja...
摘要:大揭秘目標(biāo)了解的新特性,以及版本升級(jí)的引導(dǎo)。四元數(shù)據(jù)改造我們知道以前的版本只有注冊(cè)中心,注冊(cè)中心的有數(shù)十個(gè)的鍵值對(duì),包含了一個(gè)服務(wù)所有的元數(shù)據(jù)。 DUBBO——2.7大揭秘 目標(biāo):了解2.7的新特性,以及版本升級(jí)的引導(dǎo)。 前言 我們知道Dubbo在2011年開(kāi)源,停止更新了一段時(shí)間。在2017 年 9 月 7 日,Dubbo 悄悄的在 GitHub 發(fā)布了 2.5.4 版本。隨后,版本...
摘要:當(dāng)提供程序線程池耗盡時(shí),不能發(fā)送到使用者端。一些錯(cuò)誤修正動(dòng)態(tài)配置不能刪除,支持參數(shù),監(jiān)控統(tǒng)計(jì)問(wèn)題等新功能支持手冊(cè)線程池耗盡時(shí)自動(dòng)堆棧轉(zhuǎn)儲(chǔ)。在注冊(cè)表無(wú)法連接時(shí)被阻止。正常關(guān)機(jī),在注冊(cè)表取消注冊(cè)和線程池關(guān)閉之間增加額外的等待時(shí)間。 dubbo分析showImg(https://segmentfault.com/img/bVbam2f?w=1726&h=686); dubbo為什么要對(duì)接sp...
摘要:前言到今天為止,正好是工作一年了。一年里有過(guò)折磨痛苦,有過(guò)成就感,一年后很欣慰能看到自己是有所收獲的。自己做出了一件很棒的事情完全可以拿去和別人炫耀,比如你用了一個(gè)很好的設(shè)計(jì)模式,比如你優(yōu)化了一個(gè)功能讓他快了倍,比如你開(kāi)發(fā)了一個(gè)很棒的工具。 前言 到今天為止,正好是工作一年了。一年里有過(guò)折磨痛苦,有過(guò)成就感,一年后很欣慰能看到自己是有所收獲的。記錄如下,如有不當(dāng),還望指點(diǎn)。 技術(shù) 看...
摘要:英文全名為,也叫遠(yuǎn)程過(guò)程調(diào)用,其實(shí)就是一個(gè)計(jì)算機(jī)通信協(xié)議,它是一種通過(guò)網(wǎng)絡(luò)從遠(yuǎn)程計(jì)算機(jī)程序上請(qǐng)求服務(wù)而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議。 Hello,Dubbo 你好,dubbo,初次見(jiàn)面,我想和你交個(gè)朋友。 Dubbo你到底是什么? 先給出一套官方的說(shuō)法:Apache Dubbo是一款高性能、輕量級(jí)基于Java的RPC開(kāi)源框架。 那么什么是RPC? 文檔地址:http://dubbo.a...
閱讀 2373·2021-11-22 12:01
閱讀 2095·2021-11-12 10:34
閱讀 4609·2021-09-22 15:47
閱讀 2916·2019-08-30 15:56
閱讀 2921·2019-08-30 15:53
閱讀 2469·2019-08-30 13:53
閱讀 3472·2019-08-29 15:35
閱讀 3182·2019-08-29 12:27