motan源码分析七:序列化
motan的序列化支持两种协议,一种是json,另一种是hessian2。主要涉及到的类和接口是是:FastJsonSerialization、Hessian2Serialization、Serialization、Codec、AbstractCodec、NettyDecoder、NettyEncoder、DefaultRpcCodec和CompressRpcCodec等。
1.FastJsonSerialization使用json作为数据交换协议,Hessian2Serialization使用hessian2作为数据交换协议
@SpiMeta(name = "hessian2") public class Hessian2Serialization implements Serialization { @Override public byte[] serialize(Object data) throws IOException {//使用hessan2进行序列化 ByteArrayOutputStream bos = new ByteArrayOutputStream(); Hessian2Output out = new Hessian2Output(bos); out.writeObject(data); out.flush(); return bos.toByteArray(); } @SuppressWarnings("unchecked") @Override public <T> T deserialize(byte[] data, Class<T> clz) throws IOException {//使用hessan2进行反序列化 Hessian2Input input = new Hessian2Input(new ByteArrayInputStream(data)); return (T) input.readObject(clz); } }
2.motan支持压缩和非压缩两种方式
public byte[] encode(Channel channel, Object message) throws IOException { if (needEncodeV1(message)) {//判断使用哪个版本的encode,decode同样 return v1Codec.encode(channel, message); } else { // 使用v2压缩版本 return encodeV2(channel, message);//使用压缩版本的encode } } public byte[] encodeV2(Channel channel, Object message) throws IOException { try { if (message instanceof Request) { return encodeRequest(channel, (Request) message);//序列化并压缩request对象 } else if (message instanceof Response) { return encodeResponse(channel, (Response) message);//序列化并压缩response对象 } } catch (Exception e) { if (ExceptionUtil.isMotanException(e)) { throw (RuntimeException) e; } else { throw new MotanFrameworkException("encode error: isResponse=" + (message instanceof Response), e, MotanErrorMsgConstant.FRAMEWORK_ENCODE_ERROR); } } throw new MotanFrameworkException("encode error: message type not support, " + message.getClass(), MotanErrorMsgConstant.FRAMEWORK_ENCODE_ERROR); } private byte[] encodeRequest(Channel channel, Request request) throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ObjectOutput output = createOutput(outputStream); addMethodInfo(output, request); //拿到hessian2或fasjson处理对象 Serialization serialization = ExtensionLoader.getExtensionLoader(Serialization.class).getExtension( channel.getUrl().getParameter(URLParamType.serialize.getName(), URLParamType.serialize.getValue())); if (request.getArguments() != null && request.getArguments().length > 0) { for (Object obj : request.getArguments()) { serialize(output, obj, serialization);//序列化 } } if (request.getAttachments() == null || request.getAttachments().isEmpty()) { // empty attachments output.writeShort(0); } else { // 需要copy一份attachment进行签名替换,这样在失败重试时原始的request信息不会变更 Map<String, String> attachments = copyMap(request.getAttachments()); replaceAttachmentParamsBySign(channel, attachments); addAttachment(output, attachments); } output.flush(); byte[] body = outputStream.toByteArray(); byte flag = MotanConstants.FLAG_REQUEST; output.close(); Boolean usegz = channel.getUrl().getBooleanParameter(URLParamType.usegz.getName(), URLParamType.usegz.getBooleanValue()); int minGzSize = channel.getUrl().getIntParameter(URLParamType.mingzSize.getName(), URLParamType.mingzSize.getIntValue()); return encode(compress(body, usegz, minGzSize), flag, request.getRequestId());//压缩处理 }
3.通过NettyDecoder和NettyEncoder与netty框架进行结合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | protected Object encode(ChannelHandlerContext ctx, Channel nettyChannel, Object message) throws Exception { long requestId = getRequestId(message); //获取requestId byte [] data = null ; if (message instanceof Response) { try { data = codec.encode(client, message); } catch (Exception e) { LoggerUtil.error( "NettyEncoder encode error, identity=" + client.getUrl().getIdentity(), e); Response response = buildExceptionResponse(requestId, e); data = codec.encode(client, response); } } else { data = codec.encode(client, message); //调用DefaultRpcCodec或压缩的codec来编码 } byte [] transportHeader = new byte [MotanConstants.NETTY_HEADER]; ByteUtil.short2bytes(MotanConstants.NETTY_MAGIC_TYPE, transportHeader, 0 ); transportHeader[ 3 ] = getType(message); ByteUtil.long2bytes(getRequestId(message), transportHeader, 4 ); ByteUtil.int2bytes(data.length, transportHeader, 12 ); return ChannelBuffers.wrappedBuffer(transportHeader, data); } |
分类:
motan源码分析
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?