阅读更多
1 前言
本篇博文以DefaultChannelHandlerContext为例对ChannelHandler的结构进行分析
2 继承结构
2.1 ChannelOutboundInvoker
ChannelOutboundInvoker接口定义了与ChannelOutboundHandler相似的方法
2.2 ChannelInboundInvoker
ChannelInboundInvoker接口定义了与ChannelInboundHandler相似的方法
2.3 AttributeMap
AttributeMap接口定义了一种用于添加关键字以及判断关键字是否存在的Map
2.4 DefaultAttributeMap
DefaultAttributeMap抽象类对AttributeMap接口提供了基本的实现
2.5 ChannelHandlerContext
该接口作为Handler的上下文,继承自ChannelOutboundInvoker以及ChannelInboundInvoker接口,于是包含了触发这些Handler特定方法的方法
此外,ChannelHandlerContext作为Handler的上下文
- 与Channel一一对应
- 与EventExecutor一一对应
- 与Handler一一对应
- 与Pipeline一一对应
3 AbstractChannelHandlerContext
AbstractChannelHandlerContext抽象类为ChannelHandlerContext接口提供了基础实现
AbstractChannelHandlerContext包含如下重要字段
boolean inbound
:用于标记当前持有的Handler是否为ChannelInbondHandlerboolean outbound
:用于标记当前持有的Handler是否为ChannelOutnbondHandlerDefaultChannelPipeline pipeline
:关联的DefaultChannelPipelineboolean ordered
:关联的executor是否是OrderedEventExecutorEventExecutor executor
:关联的EventExecutor,用于执行所有的异步任务
以fireChannelRead
为例,分析一下Handler特定生命周期如何被触发,以及在同一个生命周期中,调用过程如何在各个ChannelHandlerContext之间的传递
- 首先调用findContextInbound()方法,从当前位置开始(当前ChannelHandlerContext位于双向链表中的位置)向后寻找下一个Inbond类型的ChannelHandlerContext
- 通过静态方法invokeChannelRead触发ChannelRead方法
- 同步或者异步方式触发指定ChannelHandlerContext的channelRead方法
- 如果在该Handler的channelRead方法中包含
ctx.channelRead(ctx,msg)
,那么该条执行链路就会沿着双向链表向后传递
1 | public ChannelHandlerContext fireChannelRead(final Object msg) { |
4 DefaultChannelHandlerContext
DefaultChannelHandlerContext包含如下重要字段
ChannelHandler handler
:持有的Handler