`
xiaoheliushuiya
  • 浏览: 402443 次
文章分类
社区版块
存档分类
最新评论

Hessian源码浅析-HessianProxy

 
阅读更多

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

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

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

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

Proxy是由HessianProxyFactory创建

HessianProxyFactory的create方法

  1. publicObjectcreate(Class<?>api,URLurl,ClassLoaderloader){
  2. if(api==null)
  3. thrownewNullPointerException(
  4. "apimustnotbenullforHessianProxyFactory.create()");
  5. InvocationHandlerhandler=null;
  6. //api远程接口
  7. handler=newHessianProxy(url,this,api);
  8. returnProxy.newProxyInstance(loader,newClass[]{api,HessianRemoteObject.class},handler);
  9. }

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

  1. publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)
  2. throwsThrowable{
  3. StringmangleName;
  4. //从缓存中获取methodName
  5. synchronized(_mangleMap){
  6. mangleName=_mangleMap.get(method);
  7. }
  8. //如果缓存中没有
  9. if(mangleName==null){
  10. StringmethodName=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. Objectvalue=args[0];
  17. if(value==null||!Proxy.isProxyClass(value.getClass()))
  18. returnBoolean.FALSE;
  19. ObjectproxyHandler=Proxy.getInvocationHandler(value);
  20. if(!(proxyHandlerinstanceofHessianProxy))
  21. returnBoolean.FALSE;
  22. HessianProxyhandler=(HessianProxy)proxyHandler;
  23. returnnewBoolean(_url.equals(handler.getURL()));
  24. }elseif(methodName.equals("hashCode")&&params.length==0)
  25. returnnewInteger(_url.hashCode());
  26. elseif(methodName.equals("getHessianType"))
  27. returnproxy.getClass().getInterfaces()[0].getName();
  28. elseif(methodName.equals("getHessianURL"))
  29. return_url.toString();
  30. elseif(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. InputStreamis=null;
  44. HessianConnectionconn=null;
  45. try{
  46. //序列化方法名称参数向服务端发出请求
  47. //mangleName方法定义可能是methodName_参数类型_参数类型..
  48. //args参数
  49. conn=sendRequest(mangleName,args);
  50. //获得HttpURLConnection的输入流
  51. is=conn.getInputStream();
  52. AbstractHessianInputin;
  53. intmajor=is.read();
  54. intminor=is.read();
  55. in=_factory.getHessianInput(is);
  56. in.startReplyBody();
  57. //反序列化服务端返回结果
  58. Objectvalue=in.readObject(method.getReturnType());
  59. if(valueinstanceofInputStream){
  60. value=newResultInputStream(conn,is,in,(InputStream)value);
  61. is=null;
  62. conn=null;
  63. }else
  64. in.completeReply();
  65. //返回最终结果
  66. returnvalue;
  67. }catch(HessianProtocolExceptione){
  68. thrownewHessianRuntimeException(e);
  69. }finally{
  70. //..略
  71. }
  72. }

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

  1. protectedHessianConnectionsendRequest(StringmethodName,Object[]args)
  2. throwsIOException{
  3. //包装了javaHttpURLConnection
  4. HessianConnectionconn=null;
  5. conn=_factory.getConnectionFactory().open(_url);
  6. booleanisValid=false;
  7. try{
  8. addRequestHeaders(conn);
  9. OutputStreamos=null;
  10. try{
  11. os=conn.getOutputStream();
  12. }catch(Exceptione){
  13. thrownewHessianRuntimeException(e);
  14. }
  15. AbstractHessianOutputout=_factory.getHessianOutput(os);
  16. //序列化
  17. out.call(methodName,args);
  18. out.flush();
  19. //发出网络请求
  20. conn.sendRequest();
  21. isValid=true;
  22. returnconn;
  23. }finally{
  24. if(!isValid&&conn!=null)
  25. conn.destroy();
  26. }
  27. }

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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics