这篇文章来分析一个比较简单的handler--ChannelInitializer,这个在我们创建serverbootstrap的时候会经常用到,它用于对刚刚接收的channel进行初始化。。。
ServerBootstrap b = new ServerBootstrap(); //构建serverbootstrap对象
b.group(bossGroup, workerGroup); //设置时间循环对象,前者用来处理accept事件,后者用于处理已经建立的连接的io
b.channel(NioServerSocketChannel.class); //用它来建立新accept的连接,用于构造serversocketchannel的工厂类
b.childHandler(new ChannelInitializer<SocketChannel>(){ //为accept channel的pipeline预添加的inboundhandler
@Override //当新连接accept的时候,这个方法会调用
protected void initChannel(SocketChannel ch) throws Exception {
// TODO Auto-generated method stub
ch.pipeline().addLast(new MyChannelHandler()); //为当前的channel的pipeline添加自定义的处理函数
}
});
//bind方法会创建一个serverchannel,并且会将当前的channel注册到eventloop上面,
//会为其绑定本地端口,并对其进行初始化,为其的pipeline加一些默认的handler
ChannelFuture f = b.bind(80).sync();
f.channel().closeFuture().sync(); //相当于在这里阻塞,直到serverchannel关闭
这里我们可以说明一下它的应用场景:
(1)首先serversocketchannel中accept到socketchannel
(2)将这个用户定义的ChannelInitailizer加入到这个channel的pipeline上面去。。。这样,这个handler就可以用于处理当前这个channel上面的一些事件。。。
我们还是先来看看它的继承体系吧:
本文出处:http://www.xuebuyuan.com/2041554.html
最上面的两个接口,前一篇文章已经有讲过,这个netty的handler定义中最为顶层的接口,接下来就是adapter,其实他们都是抽象类,无非是实现前面接口的方法,而且实现的很简单。。。我们首先以ChannelStateHandlerAdapter为例子来说明:
public abstract class ChannelStateHandlerAdapter extends ChannelHandlerAdapter implements ChannelStateHandler {
/**
* Calls {@link ChannelHandlerContext#fireChannelRegistered()} to forward
* to the next {@link ChannelStateHandler} in the {@link ChannelPipeline}.
*
* Sub-classes may override this method to change behavior.
*/
@Override
//调用当前的这个handler的context的fireChannelRegistered方法,相当于是会向下寻找下一个stathandler,调用其的fireChannelRegistered方法
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelRegistered();
}
/**
* Calls {@link ChannelHandlerContext#fireChannelUnregistered()} to forward
* to the next {@link ChannelStateHandler} in the {@link ChannelPipeline}.
*
* Sub-classes may override this method to change behavior.
*/
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelUnregistered();
}
/**
* Calls {@link ChannelHandlerContext#fireChannelActive()} to forward
* to the next {@link ChannelStateHandler} in the {@link ChannelPipeline}.
*
* Sub-classes may override this method to change behavior.
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelActive();
}
/**
* Calls {@link ChannelHandlerContext#fireChannelInactive()} to forward
* to the next {@link ChannelStateHandler} in the {@link ChannelPipeline}.
*
* Sub-classes may override this method to change behavior.
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelInactive();
}
/**
* Calls {@link ChannelHandlerContext#fireChannelReadSuspended()} to forward
* to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
*
* Sub-classes may override this method to change behavior.
*/
@Override
public void channelReadSuspended(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelReadSuspended();
}
/**
* Calls {@link ChannelHandlerContext#fireUserEventTriggered(Object)} to forward
* to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
*
* Sub-classes may override this method to change behavior.
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
throws Exception {
ctx.fireUserEventTriggered(evt);
}
}
它实现的方法都是直接调用当前handler的context的相应的方法,然而这些方法将会在pipeline上面从前到后寻找stathandler来处理。。。(state是从前到后,operation是从后到前、、)
至于ChannelHandlerAdapter就更简单了,直接实现空方法什么的,这里就不列出来了。。。
接下来我们来看ChannelInitializer的定义吧,它从写了channelRegistered以及inboundBufferUpdated两个方法,另外定义了一个抽象方法initChannel留给用户定义的类来实现,我们来看看channelRegistered方法的定义吧:
public final void channelRegistered(ChannelHandlerContext ctx)
throws Exception {
boolean removed = false;
boolean success = false;
try {
//调用用户定义的init函数对当前的channel进行初始化
initChannel((C) ctx.channel());
ctx.pipeline().remove(this); //从当前的pipeline上面将当前的handler移除,因为没有什么用了
removed = true;
ctx.fireChannelRegistered(); //激活下面的一个stathandler的channelRegistered方法,(pipeline从前到后)
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();
}
}
}
这里代码比较简单,而且注释也说的很明白了,也就是调用在用户具体定义的initChannel函数来对当前的channel进行一些初始化的操作,并且会在当前的pipeline上面将当前这个ChannelInitializer移除。。。因为没有用了。。。
这里也就告诉了我们ChannelInitializer的用法,也就是要自己定义initChannel函数,当当前的channel被注册到eventloop上面之后,会用该用户定义的函数来初始化channel,一般都是一些加入handler的操作。。。
好了这里ChannelInitializer就分析的差不多了吧。。。接下来再分析别的handler吧。。。