Netty源码篇 ChannelInitializer
前言
ChannelInitializer
是 netty
提供的用来向 channel 的 pipeline 添加 hander 的入口ChannelInitializer
的初始化过程只能执行一次, 一旦被执行就会将该 ChannelInitializer
移除 pipeline
示例代码
// 启动 netty 服务器
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(boosGroup, workGroup)
.channel(NioServerSocketChannel.class)
//NettyClientInitializer 这里 配置 netty 对消息的处理器
.childHandler(new NettyServerInitializer(serviceProvider));
// 同步阻塞
ChannelFuture channelFuture = bootstrap.bind(port).sync();
源码解析
// 抽象方法, 需要子类实现
protected abstract void initChannel(C ch) throws Exception;
// 初始化 channel 方法
private boolean initChannel(ChannelHandlerContext ctx) throws Exception {
// initMap 是一个 set, 因此, 这个 if 里面的只会进一次, 意思是说, 每个 ctx 只能初始化一次
if (initMap.add(ctx)) {
try {initChannel((C) ctx.channel());} catch (Throwable cause) {exceptionCaught(ctx, cause);
} finally {
// 注意这里: 这里说明一旦初始化完成这个 ChannelInitializer 就将从 pipeline 中移除
if (!ctx.isRemoved()) {ctx.pipeline().remove(this);}
}
return true;
}
return false;
}
@Override
@SuppressWarnings("unchecked")
public final void channelRegistered(ChannelHandlerContext ctx) throws Exception {
// 初始化 channel, 为 true 表示这个 ctx 是第一次初始化, 可能会向 pipeline 中加入了 handler
// 所以需要从 pipeline 的头部开始重新执行 channelRegistered()
if (initChannel(ctx)) {ctx.pipeline().fireChannelRegistered();
removeState(ctx);
} else {
// 否则说明这个 ctx 已经初始化过了, 不会再像 pipline 中加入 handler 了
ctx.fireChannelRegistered();}
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
if (ctx.channel().isRegistered()) {
if (initChannel(ctx)) {removeState(ctx);
}
}
}
License:
CC BY 4.0