Netty源码分析第7章(编码器和写数据)---->第2节: MessageToByteEncoder

 

Netty源码分析第七章: Netty源码分析html

 

第二节: MessageToByteEncoderpromise

 

同解码器同样, 编码器中也有一个抽象类叫MessageToByteEncoder, 其中定义了编码器的骨架方法, 具体编码逻辑交给子类实现源码分析

解码器一样也是个handler, 将写出的数据进行截取处理, 咱们在学习pipeline中咱们知道, 写数据的时候会传递write事件, 传递过程当中会调用handler的write方法, 因此编码器码器能够重写write方法, 将数据编码成二进制字节流而后再继续传递write事件学习

首先看MessageToByteEncoder的类声明:编码

public abstract class MessageToByteEncoder<I> extends ChannelOutboundHandlerAdapter{ //省略类体 }

这里继承ChannelOutboundHandlerAdapter, 说明是个outBoundhandler, 咱们知道write事件是个outBound事件, 而outBound事件只能经过outBoundHandler进行传输spa

write事件传播过程当中要调用handler的write方法code

咱们跟到MessageToByteEncoder的write方法中:htm

public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { ByteBuf buf = null; try { if (acceptOutboundMessage(msg)) { @SuppressWarnings("unchecked") I cast = (I) msg; buf = allocateBuffer(ctx, cast, preferDirect); try { encode(ctx, cast, buf); } finally { ReferenceCountUtil.release(cast); } if (buf.isReadable()) { ctx.write(buf, promise); } else { buf.release(); ctx.write(Unpooled.EMPTY_BUFFER, promise); } buf = null; } else { ctx.write(msg, promise); } } catch (EncoderException e) { throw e; } catch (Throwable e) { throw new EncoderException(e); } finally { if (buf != null) { buf.release(); } } }

首先经过 if (acceptOutboundMessage(msg)) 判断当前对象是否可处理对象

若是可处理, 则进入if块中的逻辑, 若是不能处理, 则进入else块, 经过ctx.write(msg, promise)继续传递write事件blog

咱们看if块中

 I cast = (I) msg 这里是强制类型转换, 转换成I类型, I类型是个泛型, 具体类型由用户定义

 buf = allocateBuffer(ctx, cast, preferDirect) 这里进行缓冲区分配

跟到allocateBuffer方法中:

protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, @SuppressWarnings("unused") I msg, boolean preferDirect) throws Exception { if (preferDirect) { return ctx.alloc().ioBuffer(); } else { return ctx.alloc().heapBuffer(); } }

这里会直接经过ctx的内存分配器进行内存分配, 经过判断preferDirect来分配堆内存或者堆外内存, 默认状况下是分配堆外内存

有关内存分配, 咱们以前已经作过相关的剖析

回到write方法中:

内存分配结束以后会调用encode(ctx, cast, buf)方法进行编码, 该类由子类实现

子类能够经过继承该类, 重写encode方法, 将参数对象cast编码成字节写入到传入的ByteBuf中, 就完成了编码工做

编码完成后后, 会经过ReferenceCountUtil.release(cast)将cast对象释放

 if (buf.isReadable()) 这里判断buf是否有可读字节, 若是有可读字节, 则继续传递write事件

若是没有可读字节, 则将buf进行释放, 继续传播write事件, 传递一个空的ByteBuf

最后将buf设置为空

以上就是有关抽象编码器的抽象逻辑, 具体的编码逻辑还须要其子类去作

 

上一节: writeAndlush事件传播

下一节: 写buffer队列

相关文章
相关标签/搜索