Hessian源码浅析-HessianProxy

转载自:http://blog.csdn.net/java2000_wl/article/details/7560393

Hessian客户端主要是通过proxy代理来实现 当客户端调用远程接口方法时 会被HessianProxy 代理  HessianProxy invoke方法主要做以下工作

1.把调用的 方法名称 参数 序列化

2.通过HttpURLConnection向服务端发送调用请求

3.服务端返回的结果 反序列化

Proxy是由HessianProxyFactory创建

HessianProxyFactory的create方法

  1. public Object create(Class<?> api, URL url, ClassLoader loader) {  
  2.     if (api == null)  
  3.         throw new NullPointerException(  
  4.                 "api must not be null for HessianProxyFactory.create()");  
  5.     InvocationHandler handler = null;  
  6.     //api  远程接口  
  7.     handler = new HessianProxy(url, this, api);  
  8.     return Proxy.newProxyInstance(loader, new Class[] { api, HessianRemoteObject.class }, handler);  
  9. }  

当调用远程接口的方法时 会激活HessianProxy代理的invoke方法 invoke方法主要向服务端发送请求 反序列化服务端返回的结果

  1. public Object invoke(Object proxy, Method method, Object[] args)  
  2.             throws Throwable {  
  3.         String mangleName;  
  4.         // 从缓存中获取methodName  
  5.         synchronized (_mangleMap) {  
  6.             mangleName = _mangleMap.get(method);  
  7.         }  
  8.         // 如果缓存中没有  
  9.         if (mangleName == null) {  
  10.             String methodName = method.getName();  
  11.             Class<?>[] params = method.getParameterTypes();  
  12.             //如果是 equals, hashcode ,getHessianType,getHessianURL   
  13.             //直接调用url的对应方法返回结果   不会向服务端发送请求  
  14.             if (methodName.equals("equals") && params.length == 1  
  15.                     && params[0].equals(Object.class)) {  
  16.                 Object value = args[0];  
  17.                 if (value == null || !Proxy.isProxyClass(value.getClass()))  
  18.                     return Boolean.FALSE;  
  19.                 Object proxyHandler = Proxy.getInvocationHandler(value);  
  20.                 if (!(proxyHandler instanceof HessianProxy))  
  21.                     return Boolean.FALSE;  
  22.                 HessianProxy handler = (HessianProxy) proxyHandler;  
  23.                 return new Boolean(_url.equals(handler.getURL()));  
  24.             } else if (methodName.equals("hashCode") && params.length == 0)  
  25.                 return new Integer(_url.hashCode());  
  26.             else if (methodName.equals("getHessianType"))  
  27.                 return proxy.getClass().getInterfaces()[0].getName();  
  28.             else if (methodName.equals("getHessianURL"))  
  29.                 return _url.toString();  
  30.             else if (methodName.equals("toString") && params.length == 0)  
  31.                 return "HessianProxy[" + _url + "]";  
  32.             //重载方法支持 默认false  
  33.             if (!_factory.isOverloadEnabled())  
  34.                 mangleName = method.getName();  
  35.             else  
  36.                 //重载方法处理  最终已  methodName_参数类型_参数类型..形式返回  
  37.                 mangleName = mangleName(method);  
  38.             //缓存起来  
  39.             synchronized (_mangleMap) {  
  40.                 _mangleMap.put(method, mangleName);  
  41.             }  
  42.         }  
  43.         InputStream is = null;  
  44.         HessianConnection conn = null;  
  45.         try {  
  46.             //序列化 方法名称  参数  向服务端发出请求    
  47.             //mangleName 方法定义 可能是methodName_参数类型_参数类型..   
  48.             //args 参数  
  49.             conn = sendRequest(mangleName, args);  
  50.             //获得HttpURLConnection 的输入流  
  51.             is = conn.getInputStream();  
  52.             AbstractHessianInput in;  
  53.             int major = is.read();  
  54.             int minor = is.read();  
  55.             in = _factory.getHessianInput(is);  
  56.             in.startReplyBody();  
  57.             //反序列化服务端返回结果   
  58.             Object value = in.readObject(method.getReturnType());  
  59.             if (value instanceof InputStream) {  
  60.                 value = new ResultInputStream(conn, is, in, (InputStream) value);  
  61.                 is = null;  
  62.                 conn = null;  
  63.             } else  
  64.                 in.completeReply();  
  65.             //返回最终结果  
  66.             return value;  
  67.         } catch (HessianProtocolException e) {  
  68.             throw new HessianRuntimeException(e);  
  69.         } finally {  
  70.         //..略  
  71.         }  
  72.     }  

sendRequest 方法主要序列化请求信息(方法,参数) 然后向服务端发送请求  HessianConnection包装了HttpURLConnection

  1. protected HessianConnection sendRequest(String methodName, Object[] args)  
  2.             throws IOException {  
  3.         //包装了java HttpURLConnection  
  4.         HessianConnection conn = null;  
  5.         conn = _factory.getConnectionFactory().open(_url);  
  6.         boolean isValid = false;  
  7.   
  8.         try {  
  9.             addRequestHeaders(conn);  
  10.             OutputStream os = null;  
  11.             try {  
  12.                 os = conn.getOutputStream();  
  13.             } catch (Exception e) {  
  14.                 throw new HessianRuntimeException(e);  
  15.             }  
  16.             AbstractHessianOutput out = _factory.getHessianOutput(os);  
  17.             //序列化  
  18.             out.call(methodName, args);  
  19.             out.flush();  
  20.             //发出网络请求  
  21.             conn.sendRequest();  
  22.             isValid = true;  
  23.             return conn;  
  24.         } finally {  
  25.             if (!isValid && conn != null)  
  26.                 conn.destroy();  
  27.         }  
  28.     }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值