Netty4 2_ChannelInitializer

在上一篇博客中,我们看到例子中有一段代码


try  
        {  
            // 一个服务器助手类  
            ServerBootstrap b = new ServerBootstrap();  
            b.group(bossGroup, workerGroup)  
                    //用它来建立新accept的连接,用于构造serversocketchannel的工厂类  
                    .channel(NioServerSocketChannel.class)  
                    //在serverBootstrap内部用该handler去处理实例化的channel  
                    .childHandler(new ChannelInitializer<SocketChannel>()
                    {  
                         //当有新accept的时候,这个方法会调用  
                        @Override  
                        public void initChannel(SocketChannel ch) 
                                throws Exception  
                        {  
                            ch.pipeline().addLast(new DiscardServerHandler());  
                        }  
                    });  
  
            // 绑定并等待accept到来的连接  
            ChannelFuture f = b.bind(port).sync();  
  
              
            //关闭服务器  
            f.channel().closeFuture().sync();  
        } finally  
        {  
            workerGroup.shutdownGracefully();  
            bossGroup.shutdownGracefully();  
        }  
    }  


其中加入ServerBootstrap中处理channel却是一个ChannelInitializer ,这是怎么回事呢,不是应该相应的ChannelHandler吗?


我们来看一下Channelnitializer源代码吧

public abstract class ChannelInitializer<C extends Channel> extends ChannelInboundHandlerAdapter {

    private static final InternalLogger logger = InternalLoggerFactory.getInstance(ChannelInitializer.class);

    /**
     * 这个方法会在Channle被注册时候调用,在方法返回之后,这个实例会在Channel对应的ChannelPipeline中删除
     *
     * @param ch            the {@link Channel} which was registered.
     * @throws Exception    is thrown if an error occurs. In that case the {@link Channel} will be closed.
     */
    protected abstract void initChannel(C ch) throws Exception;

    @SuppressWarnings("unchecked")
    @Override
    public final void channelRegistered(ChannelHandlerContext ctx)
            throws Exception {
        boolean removed = false;
        boolean success = false;
        try {
            initChannel((C) ctx.channel());
            ctx.pipeline().remove(this);
            removed = true;
            ctx.fireChannelRegistered();
            success = true;
        } catch (Throwable t) {
            logger.warn("Failed to initialize a channel. Closing: " + ctx.channel(), t);
        } finally {
            if (!removed) {
                ctx.pipeline().remove(this);
            }
            if (!success) {
                ctx.close();
            }
        }
    }
}

从上面可以看出ChannelInitializer也是一个ChannelHandler,只是ChannelInitializer的主要任务不是对IO进行处理,而更多的负责对注册到EventGroup的Channel进行init处理,其中大多是进行加入Handler的处理,也就是上一博客中我们所看到的加入了一个自定义ChannelHandler


那他是怎么实现在ChannelInitializer中进行相应的channel的init的呢

他的调用过程这样的




在这里请先记得ChannelPipeline、ChannelHandlerContext以及ChannelHandler三者的关系(在以后还会介绍)


所以呢,上面的流程就是在Channel对应的ChannelPipeline中调用它的register方法,再使得channelContextPipeline调用它的相应的register方法,最后才是ChannelInitializer(它也是一个ChannelHandler)


上面流程中在DefaultChannelPipeline中



head是一个ChannelHandlerContext,而我们再看一下DefaultChannelHandlerContext



最后就是我们在上文中ChannelInitializer的代码了


最后就是我们上一节课例子中的ChannelInitializer内部类在ChannelPipeline中加入新的ChannelContext(对应自定义的ChannelHandler)了


至此,你会发现ChannelHandler是怎么加入在ChannelPipeline中,对Channel进行处理了



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值