参考
https://blog.csdn.net/fst438060684/article/details/81703748
切入点
全局切入路线:
bind->doBind->initAndRegister->ServerBoostrap.init(Channel channel)
本文将分析init中的:
p.addLast(new ChannelInitializer<Channel>() {
@Override
public void initChannel(final Channel ch) throws Exception {
...
});
所具体做的事情。也就是ChannelPipeline.addLast。
本文局部切入路线:
ChannelPipeline.addLast(EventExecutorGroup group, String name, ChannelHandler handler)
->ChannelPipeline.callHandlerAdded0
->
ctx.callHandlerAdded();
->ChannelHandler.handlerAdded
ChannelInitializer.handlerAdded
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
if (ctx.channel().isRegistered()) {
// 省去注释
if (initChannel(ctx)) { // 看此方法
removeState(ctx);
}
}
}
ChannelInitializer.initChannel
@SuppressWarnings("unchecked")
private boolean initChannel(ChannelHandlerContext ctx) throws Exception {
if (initMap.add(ctx)) {
try {
initChannel((C) ctx.channel()); // 调用用户实现的方法
}
...
finally {
ChannelPipeline pipeline = ctx.pipeline();
if (pipeline.context(this) != null) {
pipeline.remove(this); // 将自己从pipeline移除
}
}
}
return false;
}
该方法做两件事:
-
调用用户代码实现的initChannel((C) ctx.channel());
initChannel(C ch)
。 -
将ChannelInitializer从pipeline移除if (pipeline.context(this) != null) { pipeline.remove(this); // }
总结
所以,ChannelPipeline.addLast
最终会调用ChannelHandler.handlerAdded
,触发事件回调。
- 如果是ChannelInitializer实现的handlerAdded,就会调用私有方法
initChannel(ChannelHandlerContext)
,该方法会:- 调用用户实现的
initChannel(C ch)
- 不论是否出现异常,都会把自己移除。
- 调用用户实现的
- 如果是自己实现的ChannelHandler,就会调用用户的实现。(如果没对此事件实现就do nothing)
这也印证了ChannelInitializer
的类名:它是用来初始化的ChannelHandler,所以会被先添加到pipeline执行一次,调用用户实现的initChannel(C ch)
,最后把自己从pipeline移除。