Netty 中 ChannelInitializer 相对于 Channel Handler 的优势

Advantage of ChannelInitializer over Channel Handler in Netty

与直接使用 ChannelHandler 链相比,使用 ChannelInitializer 有什么优势?

例如服务器 bootstrap 我可以这样做:

bootstrap.childHandler(channel_handler);

在 channel_handler 的实现中添加我将实现以下

class simple_channel_handler implements ChannelHandler
{
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("handler added");
        ctx.pipeline().addLast(new simple_channel_handler_2());
    }
}

在 ChannelInitializer 的情况下

        ch.pipeline().addLast(
                               new channel_handler_1(), 
                               new channel_handler_2()
                             );

在每个处理程序中我都可以做

class channel_handler_1 extends ChannelInboundHandlerAdapter
{

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("Channel just became active");
        ctx.fireChannelRead(ctx); // Fire directly to channel handler 2
    }
}

那么,通道处理程序不需要了解它在何处触发通道读取的唯一优势是什么?我没有看到使用通道初始化程序的任何其他优势

根据文档(参见此处 http://netty.io/wiki/user-guide-for-4.x.html

The handler specified here will always be evaluated by a newly accepted Channel. The ChannelInitializer is a special handler that is purposed to help a user configure a new Channel. It is most likely that you want to configure the ChannelPipeline of the new Channel by adding some handlers such as DiscardServerHandler to implement your network application. As the application gets complicated, it is likely that you will add more handlers to the pipeline and extract this anonymous class into a top level class eventually.

因此 ChannelInitializer 是一种根据需要添加处理程序的简洁方法,尤其是当您有多个处理程序时。

它不会阻止让一个处理程序添加更多处理程序(就像您在第一个示例中所做的那样),例如根据上下文动态地 add/remmove 管道中的一个处理程序,但是对于 "static" 或 "default" 系列处理程序,使用 ChannelInitializer 是一种更简洁的方法,因为它非常接近 bootstrap 定义,因此更具可读性。