以上就是响应数据的解码过程,上面逻辑看起来是不是似曾相识。对的,我们在前面章节分析过 DubboCodec 的 decodeBody 方法中,关于请求数据的解码过程,该过程和响应数据的解码过程很相似。下面,我们继续分析调用结果的反序列化过程,如下:
public class DecodeableRpcResult extends RpcResult implements Codec, Decodeable { private Invocation invocation; @Override public void decode() throws Exception { if (!hasDecoded && channel != null && inputStream != null) { try { // 执行反序列化操作 decode(channel, inputStream); } catch (Throwable e) { // 反序列化失败,设置 CLIENT_ERROR 状态到 Response 对象中 response.setStatus(Response.CLIENT_ERROR); // 设置异常信息 response.setErrorMessage(StringUtils.toString(e)); } finally { hasDecoded = true; } } } @Override public Object decode(Channel channel, InputStream input) throws IOException { ObjectInput in = CodecSupport.getSerialization(channel.getUrl(), serializationType) .deserialize(channel.getUrl(), input); // 反序列化响应类型 byte flag = in.readByte(); switch (flag) { case DubboCodec.RESPONSE_NULL_VALUE: break; case DubboCodec.RESPONSE_VALUE: // ... break; case DubboCodec.RESPONSE_WITH_EXCEPTION: // ... break; // 返回值为空,且携带了 attachments 集合 case DubboCodec.RESPONSE_NULL_VALUE_WITH_ATTACHMENTS: try { // 反序列化 attachments 集合,并存储起来 setAttachments((Map<String, String>) in.readObject(Map.class)); } catch (ClassNotFoundException e) { throw new IOException(StringUtils.toString("Read response data failed.", e)); } break; // 返回值不为空,且携带了 attachments 集合 case DubboCodec.RESPONSE_VALUE_WITH_ATTACHMENTS: try { // 获取返回值类型 Type[] returnType = RpcUtils.getReturnTypes(invocation); // 反序列化调用结果,并保存起来 setValue(returnType == null || returnType.length == 0 ? in.readObject() : (returnType.length == 1 ? in.readObject((Class<?>) returnType[0]) : in.readObject((Class<?>) returnType[0], returnType[1]))); // 反序列化 attachments 集合,并存储起来 setAttachments((Map<String, String>) in.readObject(Map.class)); } catch (ClassNotFoundException e) { throw new IOException(StringUtils.toString("Read response data failed.", e)); } break; // 异常对象不为空,且携带了 attachments 集合 case DubboCodec.RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS: try { // 反序列化异常对象 Object obj = in.readObject(); if (obj instanceof Throwable == false) throw new IOException("Response data error, expect Throwable, but get " + obj); // 设置异常对象 setException((Throwable) obj); // 反序列化 attachments 集合,并存储起来 setAttachments((Map<String, String>) in.readObject(Map.class)); } catch (ClassNotFoundException e) { throw new IOException(StringUtils.toString("Read response data failed.", e)); } break; default: throw new IOException("Unknown result flag, expect '0' '1' '2', get " + flag); } if (in instanceof Cleanable) { ((Cleanable) in).cleanup(); } return this; } }Dubbo 源码分析 - 服务调用过程 (14)
内容版权声明:除非注明,否则皆为本站原创文章。