hprose for java 教程_hprose for java源码分析-4
4.1 疑竇叢生
書(shū)接上回。上回說(shuō)到,
從HproseClient.java ------------------------- (#0)
invokeHandler.handle()開(kāi)始,將經(jīng)歷一個(gè)漫長(zhǎng)的調(diào)用過(guò)程,下面把整個(gè)調(diào)用鏈粘出來(lái),先認(rèn)識(shí)下這個(gè)龐然大物。
( >>> 表示調(diào)用到, 后面 xxx.java,表示源代碼所在文件,接下來(lái)的是函數(shù)源碼 )
>>> HandlerManager.java ----------------------- ( #1 )
>>> HproseClient.java ------------------------------(#2 )
>>> HproseClient.java ------------------------------ (#3 )
534行的調(diào)用的encode()方法未貼出源碼,之后會(huì)介紹。
>>> HandlerManager.java ----------------------- (#4 )
>>> HproseClient.java ----------------------------- (#5 )
>>> HproseClient.java ------------------------------(#6)
>>> HandlerManager.java -------------------------(#7 )
>>> HproseClient.java -------------------------------(#8 )
>>> HproseClient.java ----------------------------- (#9 )
>>> HproseTcpClient.java ------------------ (#10)
>>> HproseTcpClient.java ---------------- (#11)
到#11暫告一段落,讓我喘口氣先。這段調(diào)用步驟太多了,耐心看到這里的各位看客,都是好樣的,為你點(diǎn)贊。繼續(xù),加油。
能不能簡(jiǎn)化一下呢?好像不能,這段調(diào)用一氣呵成,沒(méi)有可以跳過(guò)的步驟。然調(diào)用步驟雖多,每個(gè)函數(shù)源碼行數(shù)并不多。看來(lái),還得耐心分析一下。
初看這段調(diào)用,會(huì)被幾件事情搞暈:
1). #0中的invokeHandler.handle(name, args, context) 與 #1中的 invokeHandler(name, args, context)。
這2處都出現(xiàn)了 invokeHandler,從#0看 invokeHandler是實(shí)例對(duì)象,從#1看,invokeHandler又是函數(shù)。
invokeHandler到底是函數(shù)還是實(shí)例對(duì)象。
2). #2,#3又出現(xiàn)2處invokeHandler同名函數(shù),這比較容易理解,這2個(gè)是重載函數(shù),因?yàn)榈?個(gè)參數(shù)類型不一樣。
3). #3中的 beforeFilterHandler.handle(stream.buffer, context) 與 #4中的 beforeFilterHandler(request, context) 2處同名的 beforeFilterHandler, 暈乎乎分不清,它到底是函數(shù)還是實(shí)例對(duì)象。
還有后面 的 afterFilterHandler.handle(request, context) 與 afterFilterHandler(request, context)。
4). beforeFilterHandler,與afterFilterHandler,作用是什么?
5). #11中,首次調(diào)用142行fetch() 函數(shù)時(shí),返回的conn為null,于是send不會(huì)調(diào)用。這個(gè)調(diào)用鏈就會(huì)一步一步的返回到最初 #0處。而此時(shí),數(shù)據(jù)還沒(méi)有發(fā)向網(wǎng)絡(luò),RPC調(diào)用結(jié)果并未從服務(wù)器端返回。也就是說(shuō),在并未收到服務(wù)器端調(diào)用結(jié)果的情況下,#11處的調(diào)用鏈開(kāi)始逐層返回了,而這種返回可能會(huì)直接返回到鏈的調(diào)用最初始處,即 obj.hello("world"),這個(gè)結(jié)果是啥呢?第一回說(shuō)過(guò),在服務(wù)器端未返回結(jié)果前,客戶端會(huì)處于等待狀態(tài),直到有數(shù)據(jù)了,客戶端才會(huì)返回到最初調(diào)用處。客戶端是如何等待的,又是在哪一步等待的?
6). 最讓人頭疼的是 #7中afterFilterHandler(request, context)調(diào)用完后,后面接了一個(gè).then調(diào)用,即
afterFilterHandler(request, context).then(new Func()
同樣beforeFilterHandler也有類似情況。
再沿調(diào)用鏈仔細(xì)看一下,幾乎每處都出現(xiàn)了 .then() 的情況,這究竟是何方神圣?
疑問(wèn)很多,不過(guò)值得期待的是,這段調(diào)用是整個(gè)客戶端的核心部分,這部分弄通了,就掌握了客戶端關(guān)鍵,而其它部分是張飛吃豆芽,小菜一碟。
4.2 抽絲剝繭
接下來(lái)一個(gè)個(gè)分析上面的疑問(wèn)。
1. invokeHandler同名問(wèn)題。
事實(shí)上,在一個(gè)java類里面,成員變量與方法可以同名。如下面這個(gè)類
map方法與map成員變量雖是同名的,但java允許這樣做。
不過(guò)同名也給我們帶來(lái)了困擾,看來(lái),為了使代碼看起來(lái)更清晰些,需要人為避免一些同名出現(xiàn)。
beforeFilterHandler, afterFilterHandler也是這個(gè)問(wèn)題。
因此4.1中的問(wèn)題1), 3),一個(gè)為實(shí)例對(duì)象,一個(gè)為方法。
2. #2, #3處的重載。看#2處 invokeHandler,它覆蓋了基類(HandlerManager)中的函數(shù),基類中定義的第3個(gè)參數(shù)類型是HproseContext,但客戶端用的是 ClientContext 類型,所以定義了一個(gè) invokeHandler的
重載函數(shù),來(lái)接收 ClientContext類型,即#3處的代碼。
看到ClientContext,不禁要問(wèn),難道還有 ServiceContext?確實(shí)有,只不過(guò)ServiceContext在服務(wù)器端使用。同樣,服務(wù)器端會(huì)遇到類似的重載問(wèn)題。
由此看來(lái),方法重載雖然好用,但用多了,也會(huì)造成困擾,還是慎用吧。當(dāng)然如果只有幾個(gè)重載方法,還是可以的,如果有幾十個(gè),或上百個(gè),想分清楚誰(shuí)是誰(shuí),也是有難度的。
3. beforeFilterHandler的作用。
#3中,beforeFilterHandler.handle()調(diào)用前,先調(diào)用了encode(name,args,context),把所調(diào)方法的名稱,參數(shù),寫(xiě)入了一個(gè)流stream中。beforeFilterHandler.handle()作用是,在hprose繼續(xù)處理stream之前,準(zhǔn)確的說(shuō)是在調(diào)用
方法前( #6中341行 )
可以先給用戶去做一些處理。默認(rèn)情況下 beforeFilterHandler引用的是
HandlerManager.defaultBeforeFilterHandler 實(shí)例對(duì)象,可通過(guò)下面的方法來(lái)添加外部handle,見(jiàn)下面的代碼:
HandlerManager.java
調(diào)用addBeforeFilterHandler之后,beforeFilterHandler引用已經(jīng)改變了,此時(shí)再調(diào)用
beforeFilterHandler.handle()時(shí),首先調(diào)用的將是外部設(shè)置的那個(gè)handle了,于是在這個(gè)自定義的handle里,
可以對(duì)傳入的ByteBuffer對(duì)象做額外處理。FilterHandler接口定義如下:
4. afterFilterHandler的作用。
同樣的道理,對(duì)于afterFilterHandler.handle()是指在調(diào)用 outputFilter方法后( #6中341行 ),可以由外部做的事情,afterFilterHandler 默認(rèn)情況下引用 HandlerManager .defaultAfterFilterHandler 實(shí)例,通過(guò)下面的方法
HandlerManager.java中
來(lái)改變 afterFilterHandler的引用。
解決了 4.1中幾個(gè)疑問(wèn),還有2個(gè)有待解決,一是 .then 問(wèn)題,另外一個(gè)客戶端如何等待問(wèn)題?
先解決 .then問(wèn)題,再來(lái)看客戶端等待問(wèn)題。
請(qǐng)繼續(xù)關(guān)注下集--何方神圣。
總結(jié)
以上是生活随笔為你收集整理的hprose for java 教程_hprose for java源码分析-4的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Flask mysql 模版传参_Fla
- 下一篇: 医院治疗不孕不育多少钱啊?