责任链模式,相信大家都不陌生。tomcat、spring等各种开源产品中都有大量使用。
责任链设计模式抽象
如上图所示,责任链工程实现中,本质上是维护了一个链表或者数组,以及当前执行位置的索引currentIndex,每次调用责任链的doFilter()方法时,就会基于currentIndex执行下一个Filter。
Netty中PipeLine的设计
通过这个类图也可以大致看出netty中pipeline的设计也是采用了责任链模式,ChannelHandler外包装了一层ChannelHandlerContext,ChannelHandlerContext通过head、tail的设计可以组成一个链表,外部调用通过ChannelPipeLine作为入口,首先调用的就是ChannelHandlerContext的head,然后通过ChannelHandlerContext的next方法依次调用链表中的其他ChannelHandler。
整个实现的伪代码如下所示。
——>ChannelHandlerContext#fireChannelActive
——>Handler#channelActive(ChannelHandlerContext context){
doSth();
ctx#next()
}
ChannelHandler解读
Netty中channelHandler分为outboundHandler与inboundHandler,整个ChannelHandler按照先写后读的顺序依次执行,outboundHandler——>write——read——>inboundHandler。
例如,当某个pipeline添加handler如下,则
对于inbound的执行顺序为:1,2,3,4,5
对于outbound的执行顺序为:5,4,3,2,1
p.addLast("1", new InboundHandlerA());
p.addLast("2", new InboundHandlerB());
p.addLast("3", new OutboundHandlerA());
p.addLast("4", new OutboundHandlerB());
p.addLast("5", new InboundOutboundHandlerX());
当某个channelHandler被添加到channelPipeline之后,会自动执行该handler的handlerAdded方法。handlerAdded是handler被添加之后执行的第一个方法,也是必须要第一个执行的方法。如果handlerAdded没有被执行,handler的其他方法是无法被执行的。当调用链到来时,该handler会被自动跳过,执行下一个handler。整个执行流程如下所示。
添加ChannelHandler——>执行ChannelHandler#handlerAdded——>ChannelHandler#doSth——>fireNextChannelHandler——>
常用ChannelHandler
1)ChannelInitializer:用于当channel注册到EventLoop之后,快速初始化Channel,其原理就是ChannelInitializer本身也是个ChannelHandler,当ChannelInitializer触发HandlerAdded方法时,就会调用initChannel方法,initChannel方法是可以被重写的,用户可以自定义各种handler。
2)ServerBootstrapAcceptor:该handler主要用在ServerChannel端,用于accept新的客户端连接,并将新创建的childChannel注册到ChildEventLoop中
3)SimpleChannelInboundHandler:继承该类,可以快速实现用于处理某种类型的消息,比如快速实现处理String类型的消息等
总结一下,netty编程过程中,主要流程就是创建channel——>配置channel的pipeline——>注册channel到eventloop——>建立连接开始IO操作
更多精彩内容,欢迎关注
知乎:https://www.zhihu.com/people/mei-an-63
CSDN:https://blog.csdn.net/qq_42672856
微信: