hprose for java 教程_hprose for java源码分析-4

4.1 疑窦丛生

书接上回。上回说到,

从HproseClient.java ------------------------- (#0)

f85852f7ea4893ae1d3ae5589f30ad6c.png

invokeHandler.handle()开始,将经历一个漫长的调用过程,下面把整个调用链粘出来,先认识下这个庞然大物。

( >>> 表示调用到, 后面 xxx.java,表示源代码所在文件,接下来的是函数源码 )

>>> HandlerManager.java ----------------------- ( #1 )

65319c4142ae106b5a6668047e404063.png

>>> HproseClient.java ------------------------------(#2 )

f81e785a169b99f477a258e2a3185341.png

>>> HproseClient.java ------------------------------ (#3 )

4a1062341c5f7992b72e0a7302301826.png

534行的调用的encode()方法未贴出源码,之后会介绍。

>>> HandlerManager.java ----------------------- (#4 )

c9f74677a29b8b8b5d3974a0bb93b33c.png

>>> HproseClient.java ----------------------------- (#5 )

8c4219887d97280cad67dccb09216943.png

>>> HproseClient.java ------------------------------(#6)

5ab6ff5f67c72667529cd9bb747c2d33.png

>>> HandlerManager.java -------------------------(#7 )

b4b420b2cb8ab7237b49e7c2b7c16b2c.png

b4b420b2cb8ab7237b49e7c2b7c16b2c.png

>>> HproseClient.java -------------------------------(#8 )

c1f3a966386e282cc4c27ebea0d3f3fd.png

>>> HproseClient.java ----------------------------- (#9 )

20d8f38ccddaaadbeb9f336476d89790.png

>>> HproseTcpClient.java ------------------ (#10)

add51f1240db26e28f3d93c2b58daa64.png

>>> HproseTcpClient.java ---------------- (#11)

d9efba513c1e32929b32a0f0f459f720.png

到#11暂告一段落,让我喘口气先。这段调用步骤太多了,耐心看到这里的各位看客,都是好样的,为你点赞。继续,加油。

能不能简化一下呢?好像不能,这段调用一气呵成,没有可以跳过的步骤。然调用步骤虽多,每个函数源码行数并不多。看来,还得耐心分析一下。

初看这段调用,会被几件事情搞晕:

1). #0中的invokeHandler.handle(name, args, context) 与 #1中的 invokeHandler(name, args, context)。

这2处都出现了 invokeHandler,从#0看 invokeHandler是实例对象,从#1看,invokeHandler又是函数。

invokeHandler到底是函数还是实例对象。

2). #2,#3又出现2处invokeHandler同名函数,这比较容易理解,这2个是重载函数,因为第3个参数类型不一样。

3). #3中的 beforeFilterHandler.handle(stream.buffer, context) 与 #4中的 beforeFilterHandler(request, context) 2处同名的 beforeFilterHandler, 晕乎乎分不清,它到底是函数还是实例对象。

还有后面 的 afterFilterHandler.handle(request, context) 与 afterFilterHandler(request, context)。

4). beforeFilterHandler,与afterFilterHandler,作用是什么?

5). #11中,首次调用142行fetch() 函数时,返回的conn为null,于是send不会调用。这个调用链就会一步一步的返回到最初 #0处。而此时,数据还没有发向网络,RPC调用结果并未从服务器端返回。也就是说,在并未收到服务器端调用结果的情况下,#11处的调用链开始逐层返回了,而这种返回可能会直接返回到链的调用最初始处,即 obj.hello("world"),这个结果是啥呢?第一回说过,在服务器端未返回结果前,客户端会处于等待状态,直到有数据了,客户端才会返回到最初调用处。客户端是如何等待的,又是在哪一步等待的?

6). 最让人头疼的是 #7中afterFilterHandler(request, context)调用完后,后面接了一个.then调用,即

afterFilterHandler(request, context).then(new Func()

同样beforeFilterHandler也有类似情况。

再沿调用链仔细看一下,几乎每处都出现了 .then() 的情况,这究竟是何方神圣?

疑问很多,不过值得期待的是,这段调用是整个客户端的核心部分,这部分弄通了,就掌握了客户端关键,而其它部分是张飞吃豆芽,小菜一碟。

4.2 抽丝剥茧

接下来一个个分析上面的疑问。

1. invokeHandler同名问题。

事实上,在一个java类里面,成员变量与方法可以同名。如下面这个类

223cf0ea14492f29b5adf7157b577385.png

map方法与map成员变量虽是同名的,但java允许这样做。

不过同名也给我们带来了困扰,看来,为了使代码看起来更清晰些,需要人为避免一些同名出现。

beforeFilterHandler, afterFilterHandler也是这个问题。

因此4.1中的问题1), 3),一个为实例对象,一个为方法。

2. #2, #3处的重载。看#2处 invokeHandler,它覆盖了基类(HandlerManager)中的函数,基类中定义的第3个参数类型是HproseContext,但客户端用的是 ClientContext 类型,所以定义了一个 invokeHandler的

重载函数,来接收 ClientContext类型,即#3处的代码。

看到ClientContext,不禁要问,难道还有 ServiceContext?确实有,只不过ServiceContext在服务器端使用。同样,服务器端会遇到类似的重载问题。

由此看来,方法重载虽然好用,但用多了,也会造成困扰,还是慎用吧。当然如果只有几个重载方法,还是可以的,如果有几十个,或上百个,想分清楚谁是谁,也是有难度的。

3. beforeFilterHandler的作用。

#3中,beforeFilterHandler.handle()调用前,先调用了encode(name,args,context),把所调方法的名称,参数,写入了一个流stream中。beforeFilterHandler.handle()作用是,在hprose继续处理stream之前,准确的说是在调用

dece6dca75de20baae38b5d6e983c519.png

方法前( #6中341行 )

可以先给用户去做一些处理。默认情况下 beforeFilterHandler引用的是

HandlerManager.defaultBeforeFilterHandler 实例对象,可通过下面的方法来添加外部handle,见下面的代码:

HandlerManager.java

03c33546b6cde3f6bddb7c382955b221.png

调用addBeforeFilterHandler之后,beforeFilterHandler引用已经改变了,此时再调用

beforeFilterHandler.handle()时,首先调用的将是外部设置的那个handle了,于是在这个自定义的handle里,

可以对传入的ByteBuffer对象做额外处理。FilterHandler接口定义如下:

4bc4b9a4c7fbcf46eceaaddc894eeefc.png

4bc4b9a4c7fbcf46eceaaddc894eeefc.png

4. afterFilterHandler的作用。

同样的道理,对于afterFilterHandler.handle()是指在调用 outputFilter方法后( #6中341行 ),可以由外部做的事情,afterFilterHandler 默认情况下引用 HandlerManager .defaultAfterFilterHandler 实例,通过下面的方法

HandlerManager.java中

e4b3b4e5c55474853ce2847f6daa36b1.png

来改变 afterFilterHandler的引用。

解决了 4.1中几个疑问,还有2个有待解决,一是 .then 问题,另外一个客户端如何等待问题?

先解决 .then问题,再来看客户端等待问题。

请继续关注下集--何方神圣。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值