读书人

Hessian源码学习(2)

发布时间: 2012-06-26 10:04:13 作者: rapoo

Hessian源码学习(二)
【客户端】

我们在客户端是如何使用hessian呢?

String url = "http://localhost:8080/Hello/hello";HessianProxyFactory factory = new HessianProxyFactory();IHello helloProxy = (IHello)factory.create(IHello.class, url);System.out.println(helloProxy.sayHello());

以上代码就可以实现hessian的远程调用了,但是这些究竟是怎么实现的呢,我们一步步分析。

factory.create(IHello.class, url); 通过 HessianProxyFactory(Hessian代理工厂)创建一个代理类,具体代码如下;
public Object create(Class api, String urlName)    throws MalformedURLException{return create(api, urlName, Thread.currentThread().getContextClassLoader());}public Object create(Class api, String urlName, ClassLoader loader)    throws MalformedURLException{    URL url = new URL(urlName);// HessianProxy implements InvocationHandler     HessianProxy handler = new HessianProxy(this, url);      return Proxy.newProxyInstance(api.getClassLoader(),                  new Class[] { api, HessianRemoteObject.class }, handler);}

helloProxy.sayHello(); 实际上是调用代理类的invoke方法,我们具体看下代码:
// 获取调用的方法名以及方法参数类型String methodName = method.getName();Class []params = method.getParameterTypes();//对于以下方法直接执行本地调用而不是远程调用if (methodName.equals("equals") &&    params.length == 1 && params[0].equals(Object.class)) {    Object value = args[0];if (value == null || ! Proxy.isProxyClass(value.getClass()))        return new Boolean(false);    HessianProxy handler = (HessianProxy) Proxy.getInvocationHandler(value);return new Boolean(_url.equals(handler.getURL()));}else if (methodName.equals("hashCode") && params.length == 0)  return new Integer(_url.hashCode());else if (methodName.equals("getHessianType"))  return proxy.getClass().getInterfaces()[0].getName();else if (methodName.equals("getHessianURL"))  return _url.toString();else if (methodName.equals("toString") && params.length == 0)  return "[HessianProxy " + _url + "]"; // 判断客户端是否要求支持重载(即客户端是否设置factory.setOverloadEnabled(true); //注:3.0.2 只支持参数个数不同的重载,后面版本才真正意义上的支持重载)if (! _factory.isOverloadEnabled()) {// 不要求重载,则什么都不做    }else if (args != null)    methodName = methodName + "__" + args.length;else    methodName = methodName + "__0";   // 执行远程调用(建立http链接,设置一些http header, 序列化方法名和方法参数,执行http请求...)conn = sendRequest(methodName, args);// 从输入流中读取远程调用结果并返回给客户端is = conn.getInputStream();AbstractHessianInput in = _factory.getHessianInput(is);return in.readReply(method.getReturnType());


以上是客户端整个调用远程服务的流程(细节未涉及),总结:整个hessian远程调用可以用以下一副图概括:


读书人网 >开源软件

热点推荐