Hessian在客户端一块采用Proxy模式,当客户端调用远程接口时,HessianProxy会代理这个动作,在invoke方法中,把客户端请求的方法和参数序列化为预订格式的输出流,主要流程如下图所示:
下面我将详细解析一下invoke源码:
- public Object invoke(Object proxy, Method method, Object []args)
- throws Throwable
- {
- String mangleName;
- synchronized (_mangleMap) {
- mangleName = _mangleMap.get(method);
- }
- if (mangleName == null) {
- String methodName = method.getName();
- Class []params = method.getParameterTypes();
- // equals and hashCode are special cased
- 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 + "]";
- if (! _factory.isOverloadEnabled())
- mangleName = method.getName();
- else
- mangleName = mangleName(method);
- synchronized (_mangleMap) {
- _mangleMap.put(method, mangleName);
- }
- }
- ......
- }
这是invoke的开头,主要干的事情是把methodName缓存起来和过滤一些特殊调用,java反射是个比较耗性能的操作,把methodName缓存起来可以避免每次调用都要从method里得到methodName。另外,对equals、hashCode、getHessianType、getHessianURL等特殊方法的远程调用,HessianProxy不会走远程调用,而是直接返回。
接着往下看:
- public Object invoke(Object proxy, Method method, Object []args)
- throws Throwable
- {
- ......
- InputStream is = null;
- URLConnection conn = null;
- HttpURLConnection httpConn = null;
- try {
- conn = sendRequest(mangleName, args);
- ......
- } catch (HessianProtocolException e) {
- throw new HessianRuntimeException(e);
- } finally {
- ......
- }
- }
这段主要是把方法名和参数序列化为网络输出流,并做网络请求,具体逻辑包装在sendRequest方法中:
- protected URLConnection sendRequest(String methodName, Object []args)
- throws IOException
- {
- URLConnection conn = null;
- conn = _factory.openConnection(_url);
- boolean isValid = false;
- try {
- // Used chunked mode when available, i.e. JDK 1.5.
- if (_factory.isChunkedPost() && conn instanceof HttpURLConnection) {
- try {
- HttpURLConnection httpConn = (HttpURLConnection) conn;
- httpConn.setChunkedStreamingMode(8 * 1024);
- } catch (Throwable e) {
- }
- }
- addRequestHeaders(conn);
- OutputStream os = null;
- try {
- os = conn.getOutputStream();
- } catch (Exception e) {
- throw new HessianRuntimeException(e);
- }
- if (log.isLoggable(Level.FINEST)) {
- PrintWriter dbg = new PrintWriter(new LogWriter(log));
- os = new HessianDebugOutputStream(os, dbg);
- }
- AbstractHessianOutput out = _factory.getHessianOutput(os);
- out.call(methodName, args);
- out.flush();
- isValid = true;
- return conn;
- } finally {
- if (! isValid && conn instanceof HttpURLConnection)
- ((HttpURLConnection) conn).disconnect();
- }
- }
sendRequest的主要流程是先初始化网络连接,然后用AbstractHessianOutput包装网络输出流,调用AbstractHessianOutput.call(methodName, args)完成网络输出,这个方法的细节会在hessian io的源码解析中详细分析。
下面接着看invoke方法:
- public Object invoke(Object proxy, Method method, Object []args)
- throws Throwable
- {
- ......
- is = conn.getInputStream();
- AbstractHessianInput in = _factory.getHessianInput(is);
- in.startReply();
- Object value = in.readObject(method.getReturnType());
- if (value instanceof InputStream) {
- value = new ResultInputStream(httpConn, is, in, (InputStream) value);
- is = null;
- httpConn = null;
- }
- else
- in.completeReply();
- ......
- }
这一段主要是把输入流中取得返回值,具体是用AbstractHessianInput包装网络输入流,然后调用AbstractHessianInput.readObject从网络流中反序列化到实际返回值。
相关推荐
com.alibaba:hessian-lite:jar:3.2.1-fixed-2 hessian-lite hessian-lite-3.2.1-fixed-2.jar
赠送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-...
赠送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-...
赠送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**"源码包中,主要包含两个关键文件:"**pom.xml**"和"**src**"。 1. **pom.xml**:这是Maven项目的配置文件,定义了项目依赖、构建过程等信息。通过这个文件,我们可以看到Hessian ...
赠送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是一个轻量级的Java Remoting方案
java运行依赖jar包
总结一下,Hessian的源码分析主要关注客户端的`HessianProxy`和服务器端的`HessianSkeleton`这两个核心类。它们分别负责客户端的调用代理和服务器端的请求处理。源码中包含了方法名缓存、特殊方法的本地处理、以及...
Hessian 框架源码jar包 hessian-4.0.7-src.jar
1. **获取源码**:首先,从官方渠道或指定仓库下载hessian-lite的源码包,例如这里给出的是名为“hessian-lite-master”的压缩包。 2. **构建并安装**:解压源码包,使用Maven工具执行`mvn install`命令,将Hessian...
Hessian-lite最初是的Apache dubbo嵌入版本。 然后,此模块与Dubbo分离。 所有分支:2.5.x,2.6.x(自2.6.3起)和2.7.x都依赖于它,请查看详细信息: 现在,我们正在尝试建立一个黑森州小组以使黑森州社区的维护者...
通过阅读和分析Hessian的源码,我们可以了解其如何编码和解码各种数据类型,以及如何优化序列化和反序列化的过程。这对于优化自定义序列化逻辑或者解决Hessian使用中遇到的问题非常有帮助。 总结起来,Hessian是一...
hessian-3.1.6.jarhessian-3.1.6.jar
通过分析和实践这些源码,开发者可以深入理解如何在自己的项目中集成和使用Hessian。 6. **PPT材料**:二进制Web服务Hessian.ppt很可能是讲座的幻灯片,其中可能涵盖了Hessian的基础概念、工作流程、优缺点以及实战...
hessian-3.2.0源码,在做分布式交互时,可能要重写hessian
首先,`hessian-4.0.7.jar`文件是预编译的Hessian库,可以直接在Java项目中使用。它提供了各种类和接口,如`com.caucho.hessian.io.Hessian2Input`和`com.caucho.hessian.io.Hessian2Output`,用于序列化和反序列化...
在实际开发过程中,可能会遇到由于阿里的网络限制导致无法直接获取 hessian-lite 这个依赖的问题,此时需要用户手动下载 hessian-lite 源码,通过 Maven 安装到本地仓库以解决依赖。 【描述】中提到的 "dubbo源码...