前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >netty源码解析 Pipeline添加Handler ChannelPipeline.addLast

netty源码解析 Pipeline添加Handler ChannelPipeline.addLast

作者头像
平凡的学生族
发布2019-05-25 09:29:57
6490
发布2019-05-25 09:29:57
举报
文章被收录于专栏:后端技术后端技术

参考

https://blog.csdn.net/fst438060684/article/details/81703748

切入点

全局切入路线: bind->doBind->initAndRegister->ServerBoostrap.init(Channel channel)

本文将分析init中的:

代码语言:javascript
复制
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

代码语言:javascript
复制
@Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        if (ctx.channel().isRegistered()) {
            //  省去注释
            if (initChannel(ctx)) { // 看此方法
                removeState(ctx);
            }
        }
    }

ChannelInitializer.initChannel

代码语言:javascript
复制
 @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;
    }

该方法做两件事:

  1. initChannel((C) ctx.channel()); 调用用户代码实现的initChannel(C ch)
  2. if (pipeline.context(this) != null) { pipeline.remove(this); // } 将ChannelInitializer从pipeline移除

总结

所以,ChannelPipeline.addLast最终会调用ChannelHandler.handlerAdded,触发事件回调。

  • 如果是ChannelInitializer实现的handlerAdded,就会调用私有方法initChannel(ChannelHandlerContext),该方法会:
    1. 调用用户实现的initChannel(C ch)
    2. 不论是否出现异常,都会把自己移除
  • 如果是自己实现的ChannelHandler,就会调用用户的实现。(如果没对此事件实现就do nothing)

这也印证了ChannelInitializer的类名:它是用来初始化的ChannelHandler,所以会被先添加到pipeline执行一次,调用用户实现的initChannel(C ch),最后把自己从pipeline移除。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.03.23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参考
  • 切入点
  • ChannelInitializer.handlerAdded
  • ChannelInitializer.initChannel
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档