hprose是个开源RPC框架。支持措辞 JAVA, C#,C++,Python,PHP等一系列措辞。这里着重剖析下hprose for
java源码。
可以到 github或hprose官网下载源码。我下载的版本是2.0.36,之后以这个版本为根本展开剖析。

下载后,解压。
在eclipse中新建一个java工程 hprose,然后将下载解压目录下的src下面的代码复制到hprose工程中,可能会创造有几处编译不过,这是由于短缺了几个jar。 servlet-api.jar,
javax.websocket-api-1.0-rc4.jar
办理办法:
1. 下载tomcat,解压到某个目录,如 d:\tomcat
在hprose中添加对文件 d:\tomcat\lib\servlet-api.jar的引用
2. 下载 javax.websocket-api.jar ,在hprose工程添加其引用
经由这2步,就可以办理编译问题了。下图展示了在哪里添加引用。
下面开始hprose源码剖析之旅吧。
1.2 作甚RPC
RPC( remote procedure call),远程过程调用。要调用的过程不在本机,而是在一台做事器上。RPC调用机制使得与调用本机函数没有差别,只是RPC调用要经由网络。
1.3 RPC调用流程
1. 客户端发起一个RPC调用
2. 被调用函数的函数名,参数列表 封装成一个数据包,把数据包发往做事器端
3. 做事器未返回数据时,客户端处于等待状态
4. 做事器收到要求函数调用的数据包,根据函数名,找到对应函数,取出调用参数,然后调用。
5. 做事器返回调用结果
6. 客户端吸收到调用结果,并且将这个结果返回给调用者。
hprose框架完成的便是上面的事情,下面将逐渐展开剖析。
1.4 从哪里开始
hprose工程建好后,可以看到图示包列表,内容不少,从哪里开始呢?有道是擒贼先擒王,打蛇打七寸,须要做的事情便是先抓主干。RPC的主干是什么?便是1.3中所述的RPC调用流程,先把这个流程弄通,其他旁枝就好办了。在剖析过程中,会碰着一些细节上的障碍,不防事。各位看客,请听我逐步道来。
1.5 出发点
从hprose给出的示例中可以到客户端如何发启一个RPC调用
interface IHello { String hello(String name); }
public class TestClient {
public static void main(String[] args) {
HproseTcpClient client = new HproseTcpClient(\"大众tcp://127.0.0.1:4321/\"大众);
client.setFullDuplex(true);
client.setMaxPoolSize(1);
IHello obj = client.useService(IHello.class);
String str = obj.hello( \公众world\"大众 );
System.out.println( str );
}
}
粘代码真是摧残浪费蹂躏篇幅,没办法,为了看的清楚些,还是粘了一些。不过没粘全,像import这类语句没粘,这些可以在示例中找到。闲言少叙,还是看下重点。
1. HproseTcpClient client = new HproseTcpClient(\公众tcp://127.0.0.1:4321/\"大众);
天生一客户端实例,表示 客户端要 通过 tcp 连接 本机上的一个端口为4321 的做事器。
2. IHello obj = client.useService(IHello.class); 天生一个动态代理
3. String str = obj.hello( \"大众world\公众 ); 调用并返回结果。本步骤调用函数 hello,并不是调用客户端上的
hello函数,而是将调用数据发送到了做事器端,在做事器找到名为hello的函数,然后调用。
神奇,这统统是如何发生的?obj.hello(\"大众world\公众), 调用的是接口 IHello中的一个方法,但上面的代码没有实现 IHello接口呀。看来秘密就在第2步, 天生一个动态代理。
1.6 动态代理
动态代理是什么鬼,还能不能好好剖析了。这是只拦路虎,不办理它,无法连续下去,提高路上的障碍要想办法肃清。
前面提到了接口IHello,要想利用它,须要定义一个实现类,比如 class MyHello implements IHello{}
然后天生一个MyHello的实例,就可以调用个中的方法 hello()了。是的,定义一个实现类,然后利用。
实在MyHello便是一个代理,只不过这是自己手动定义的。动态代理是不须要手动去定义,而是自动天生了IHello的实现类。既然可以手动定义,自己定义一个实现类,直策应用不就可以了吗?为何还须要借助于动态代理呢。
事情没有这么大略。
试想,hprose框架在设计时,是无法知道用户会定义一个什么样的接口,更别提写一个实现类了。但又为了方便用户,可以通过接口来利用这个RPC框架,那就有必要做一个动态的东西出来。用户只须要把接口定义好,
然后调用框架供应的工具函数,天生一个动态代理工具,根据这个工具,去调用接口中的方法,其他事情,像连接做事器,向做事器发送数据包,等繁芜事情,统统交给框架。这便是动态代理缘由。
还是来看下源码吧。
(函数在 HproseClient.java文件内。)
函数297行,调用Proxy.newProxyInstance(),这是jdk api。
看下这个api的各个参数
参数1: ClassLoader
参数2: 接口类型列表
参数3: 一个回调
着重看下参数3,它是一个回调接口,
public interface InvocationHandler
{
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
} ( jdk中定义 )
proxy,是动态代理的实例工具
method,是要调用的方法
args,调用参 数列表
什么,还是不明白?绕来绕去的,到底想说什么。下篇揭晓其真面孔。
欲知后事如何,且听下回分解。