`
goon
  • 浏览: 184118 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

hessian——源码分析(二)------ HessianProxy《转》

 
阅读更多

Hessian在客户端一块采用Proxy模式,当客户端调用远程接口时,HessianProxy会代理这个动作,在invoke方法中,把客户端请求的方法和参数序列化为预订格式的输出流,主要流程如下图所示:

 

下面我将详细解析一下invoke源码:

 

[java] view plaincopy
  1. public Object invoke(Object proxy, Method method, Object []args)  
  2.     throws Throwable  
  3.   {  
  4.     String mangleName;  
  5.     synchronized (_mangleMap) {  
  6.       mangleName = _mangleMap.get(method);  
  7.     }  
  8.     if (mangleName == null) {  
  9.       String methodName = method.getName();  
  10.       Class []params = method.getParameterTypes();  
  11.       // equals and hashCode are special cased  
  12.       if (methodName.equals("equals")  
  13.       && params.length == 1 && params[0].equals(Object.class)) {  
  14.     Object value = args[0];  
  15.     if (value == null || ! Proxy.isProxyClass(value.getClass()))  
  16.       return new Boolean(false);  
  17.     HessianProxy handler = (HessianProxy) Proxy.getInvocationHandler(value);  
  18.     return new Boolean(_url.equals(handler.getURL()));  
  19.       }  
  20.       else if (methodName.equals("hashCode") && params.length == 0)  
  21.     return new Integer(_url.hashCode());  
  22.       else if (methodName.equals("getHessianType"))  
  23.     return proxy.getClass().getInterfaces()[0].getName();  
  24.       else if (methodName.equals("getHessianURL"))  
  25.     return _url.toString();  
  26.       else if (methodName.equals("toString") && params.length == 0)  
  27.     return "HessianProxy[" + _url + "]";  
  28.         
  29.       if (! _factory.isOverloadEnabled())  
  30.     mangleName = method.getName();  
  31.       else  
  32.         mangleName = mangleName(method);  
  33.       synchronized (_mangleMap) {  
  34.     _mangleMap.put(method, mangleName);  
  35.       }  
  36.     }  
  37.     ......  
  38. }  

 

这是invoke的开头,主要干的事情是把methodName缓存起来和过滤一些特殊调用,java反射是个比较耗性能的操作,把methodName缓存起来可以避免每次调用都要从method里得到methodName。另外,对equals、hashCode、getHessianType、getHessianURL等特殊方法的远程调用,HessianProxy不会走远程调用,而是直接返回。

接着往下看:

 

[java] view plaincopy
  1. public Object invoke(Object proxy, Method method, Object []args)  
  2.     throws Throwable  
  3.   {  
  4.     ......  
  5.     InputStream is = null;  
  6.     URLConnection conn = null;  
  7.     HttpURLConnection httpConn = null;  
  8.       
  9.     try {  
  10.              
  11.       conn = sendRequest(mangleName, args);  
  12.      ......  
  13.     } catch (HessianProtocolException e) {  
  14.       throw new HessianRuntimeException(e);  
  15.     } finally {  
  16.      ......  
  17.      }  
  18.   }  

 

这段主要是把方法名和参数序列化为网络输出流,并做网络请求,具体逻辑包装在sendRequest方法中:

 

[java] view plaincopy
  1. protected URLConnection sendRequest(String methodName, Object []args)  
  2.     throws IOException  
  3.   {  
  4.     URLConnection conn = null;  
  5.       
  6.     conn = _factory.openConnection(_url);  
  7.     boolean isValid = false;  
  8.     try {  
  9.       // Used chunked mode when available, i.e. JDK 1.5.  
  10.       if (_factory.isChunkedPost() && conn instanceof HttpURLConnection) {  
  11.     try {  
  12.       HttpURLConnection httpConn = (HttpURLConnection) conn;  
  13.       httpConn.setChunkedStreamingMode(8 * 1024);  
  14.     } catch (Throwable e) {  
  15.     }  
  16.       }  
  17.       
  18.       addRequestHeaders(conn);  
  19.       OutputStream os = null;  
  20.       try {  
  21.     os = conn.getOutputStream();  
  22.       } catch (Exception e) {  
  23.     throw new HessianRuntimeException(e);  
  24.       }  
  25.       if (log.isLoggable(Level.FINEST)) {  
  26.     PrintWriter dbg = new PrintWriter(new LogWriter(log));  
  27.     os = new HessianDebugOutputStream(os, dbg);  
  28.       }  
  29.         
  30.       AbstractHessianOutput out = _factory.getHessianOutput(os);  
  31.       out.call(methodName, args);  
  32.       out.flush();  
  33.       isValid = true;  
  34.       return conn;  
  35.     } finally {  
  36.       if (! isValid && conn instanceof HttpURLConnection)  
  37.     ((HttpURLConnection) conn).disconnect();  
  38.     }  
  39.   }  

 

sendRequest的主要流程是先初始化网络连接,然后用AbstractHessianOutput包装网络输出流,调用AbstractHessianOutput.call(methodName, args)完成网络输出,这个方法的细节会在hessian io的源码解析中详细分析。

下面接着看invoke方法:

 

[java] view plaincopy
  1. public Object invoke(Object proxy, Method method, Object []args)  
  2.     throws Throwable  
  3.   {  
  4.       ......  
  5.       is = conn.getInputStream();  
  6.       AbstractHessianInput in = _factory.getHessianInput(is);  
  7.       in.startReply();  
  8.       Object value = in.readObject(method.getReturnType());  
  9.       if (value instanceof InputStream) {  
  10.     value = new ResultInputStream(httpConn, is, in, (InputStream) value);  
  11.     is = null;  
  12.     httpConn = null;  
  13.       }  
  14.       else  
  15.     in.completeReply();  
  16.       ......  
  17.   }  

 

这一段主要是把输入流中取得返回值,具体是用AbstractHessianInput包装网络输入流,然后调用AbstractHessianInput.readObject从网络流中反序列化到实际返回值。

分享到:
评论

相关推荐

    hessian-lite-3.2.1-fixed-2.jar

    com.alibaba:hessian-lite:jar:3.2.1-fixed-2 hessian-lite hessian-lite-3.2.1-fixed-2.jar

    hessian-4.0.63-API文档-中英对照版.zip

    赠送jar包:hessian-4.0.63.jar; 赠送原API文档:hessian-4.0.63-javadoc.jar; 赠送源代码:hessian-4.0.63-sources.jar; 赠送Maven依赖信息文件:hessian-4.0.63.pom; 包含翻译后的API文档:hessian-4.0.63-...

    hessian-4.0.63-API文档-中文版.zip

    赠送jar包:hessian-4.0.63.jar; 赠送原API文档:hessian-4.0.63-javadoc.jar; 赠送源代码:hessian-4.0.63-sources.jar; 赠送Maven依赖信息文件:hessian-4.0.63.pom; 包含翻译后的API文档:hessian-4.0.63-...

    hessian-3.3.6-API文档-中英对照版.zip

    赠送jar包:hessian-3.3.6.jar 赠送原API文档:hessian-3.3.6-javadoc.jar 赠送源代码:hessian-3.3.6-sources.jar 包含翻译后的API文档:hessian-3.3.6-javadoc-API文档-中文(简体)-英语-对照版.zip 对应Maven...

    hessian-4.0.51-src

    在解压的"**hessian-4.0.51-src**"源码包中,主要包含两个关键文件:"**pom.xml**"和"**src**"。 1. **pom.xml**:这是Maven项目的配置文件,定义了项目依赖、构建过程等信息。通过这个文件,我们可以看到Hessian ...

    hessian-3.3.6-API文档-中文版.zip

    赠送jar包:hessian-3.3.6.jar; 赠送原API文档:hessian-3.3.6-javadoc.jar; 赠送源代码:hessian-3.3.6-sources.jar; 赠送Maven依赖信息文件:hessian-3.3.6.pom; 包含翻译后的API文档:hessian-3.3.6-javadoc-...

    hessian-3.0.20-src.jar

    hessian是一个轻量级的Java Remoting方案

    hessian-lite-3.2.1-fixed-2-sources.jar

    java运行依赖jar包

    hessian最新源码分析.pdf

    总结一下,Hessian的源码分析主要关注客户端的`HessianProxy`和服务器端的`HessianSkeleton`这两个核心类。它们分别负责客户端的调用代理和服务器端的请求处理。源码中包含了方法名缓存、特殊方法的本地处理、以及...

    hessian-4.0.7-src.jar

    Hessian 框架源码jar包 hessian-4.0.7-src.jar

    hessian-lite

    1. **获取源码**:首先,从官方渠道或指定仓库下载hessian-lite的源码包,例如这里给出的是名为“hessian-lite-master”的压缩包。 2. **构建并安装**:解压源码包,使用Maven工具执行`mvn install`命令,将Hessian...

    dubbo-hessian-lite:适用于Apache Dubbo的Hessian Lite

    Hessian-lite最初是的Apache dubbo嵌入版本。 然后,此模块与Dubbo分离。 所有分支:2.5.x,2.6.x(自2.6.3起)和2.7.x都依赖于它,请查看详细信息: 现在,我们正在尝试建立一个黑森州小组以使黑森州社区的维护者...

    hessian学习基础篇——序列化和反序列化

    通过阅读和分析Hessian的源码,我们可以了解其如何编码和解码各种数据类型,以及如何优化序列化和反序列化的过程。这对于优化自定义序列化逻辑或者解决Hessian使用中遇到的问题非常有帮助。 总结起来,Hessian是一...

    hessian-3.1.6.jar

    hessian-3.1.6.jarhessian-3.1.6.jar

    二进制Web服务Hessian刘骥讲座--(附源码)

    通过分析和实践这些源码,开发者可以深入理解如何在自己的项目中集成和使用Hessian。 6. **PPT材料**:二进制Web服务Hessian.ppt很可能是讲座的幻灯片,其中可能涵盖了Hessian的基础概念、工作流程、优缺点以及实战...

    hessian-3.2.0源码

    hessian-3.2.0源码,在做分布式交互时,可能要重写hessian

    Hessian-4.0.7(Jar包 + 源码)

    首先,`hessian-4.0.7.jar`文件是预编译的Hessian库,可以直接在Java项目中使用。它提供了各种类和接口,如`com.caucho.hessian.io.Hessian2Input`和`com.caucho.hessian.io.Hessian2Output`,用于序列化和反序列化...

    dubbo-hessian-lite

    在实际开发过程中,可能会遇到由于阿里的网络限制导致无法直接获取 hessian-lite 这个依赖的问题,此时需要用户手动下载 hessian-lite 源码,通过 Maven 安装到本地仓库以解决依赖。 【描述】中提到的 "dubbo源码...

Global site tag (gtag.js) - Google Analytics