59. 网状的源代码分析-ServerBootstrap绑定过程2

  

一。接上一篇

  https://blog.51cto.com/483181/2121265

  

我们继续分析doBind0 (regFuture、通道、localAddress承诺)

  
 <代码>私人ChannelFuture doBind(最终SocketAddress localAddress都){
  最后ChannelFuture regFuture=initAndRegister ();
  最终频道频道=regFuture.channel ();
  如果(regFuture.cause () !=null) {
  返回regFuture;
  }
  
  如果(regFuture.isDone ()) {//在这一点上我们知道登记是完整的和成功的。
  ChannelPromise承诺=channel.newPromise ();
  doBind0 (regFuture、通道、localAddress承诺);//3。我们这篇要分析的内容
  返回的诺言;
  其他}{
  …
  返回的诺言;
  }
  } 
  

二。doBind0

  

2.1 - 4个参数

  

如上面代码,doBind0有4个参数regFuture,通道,localAddress,承诺,它们的类型如下:
regFuture: DefaultChannelPromise
频道:NioServerSocketChannel
localAddress: SocketAddress
都承诺:DefaultChannelPromise

  

那继续往下面看代码,

  
 <代码>私有静态孔隙doBind0 (
  最后ChannelFuture regFuture,最终频道频道,
  最终SocketAddress localAddress都最终ChannelPromise承诺){//这个方法被调用之前channelRegistered()被触发。给用户处理程序设置的机会//管道的channelRegistered()实现。
  channel.eventLoop ()。执行(新Runnable () {
  @Override
  公共空间run () {
  如果(regFuture.isSuccess ()) {
  通道。bind (localAddress承诺).addListener (ChannelFutureListener.CLOSE_ON_FAILURE);
  其他}{
  promise.setFailure (regFuture.cause ());
  }
  }
  });
  } 
  

doBind0()代码很简单、调用channel.eventloop()执行了一个Runnable.channel.eventloop()调用的是AbstractChannle.eventloop ()

  
 <代码> @Override
  公共EventLoop EventLoop () {
  EventLoop EventLoop=this.eventLoop;
  如果(eventLoop==null) {
  把新的IllegalStateException(“通道不注册一个事件循环”);
  }
  返回eventLoop;
  } 
  

而this.eventLoop初始化是在注册的时候,具体可以参考上一篇结合初始化的分析

  https://blog.51cto.com/483181/2121265

  
 <代码> @Override
  公共最终无效注册(EventLoop EventLoop,最终ChannelPromise承诺){
  …
  
  AbstractChannel.this。eventLoop=eventLoop;
  …
  } 
  

它的类型是一个NioEventLoop,所以它就是往自己的线程池里面丢了一个可运行的任务
NioEventLoop的继承关系图如下:
 59。网状的源代码分析-ServerBootstrap绑定过程2

  

我们可以看一下NioEventLoop。执行(Runnable)方法。

  

2.2执行(Runnable)方法

  

这个方法的实现是在SingleThreadEventExecutor.java里面。

  
 <代码>私人最终QueuetaskQueue;
  
  @Override
  公共空间执行(Runnable任务){
  如果(任务==null) {
  把新NullPointerException(“任务”);
  }
  
  布尔inEventLoop=inEventLoop ();
  addTask(任务);
  如果(! inEventLoop) {
  startThread ();
  如果(isShutdown (),,removeTask(任务)){
  拒绝();
  }
  }
  
  如果(!addTaskWakesUp,,wakesUpForTask(任务)){
  唤醒(inEventLoop);
  }
  }
  
  保护无效addTask (Runnable任务){
  如果(任务==null) {
  把新NullPointerException(“任务”);
  }
  如果(! offerTask(任务)){
  拒绝(任务);
  }
  }
  
  最后布尔offerTask (Runnable任务){
  如果(isShutdown ()) {
  拒绝();
  }
  返回taskQueue.offer(任务);
  } 
  

它是把传入的Runnable对象放到一个taskQueue队列里面。

  

那我们继续看Runnable里面的实现,channel.bind (xxxx)

  
 <代码> channel.eventLoop ()。执行(新Runnable () {
  @Override
  公共空间run () {
  …
  通道。bind (localAddress承诺).addListener (ChannelFutureListener.CLOSE_ON_FAILURE);
  }
  }); 
  

2.3 channel.bind

  

频道的类型是NioServerSocketChannel,而绑定方法的实现类是在AbstractChannel.java里面。

  
 <代码> @Override
  公共ChannelFuture绑定(SocketAddress localAddress都,ChannelPromise承诺){
  返回管道。bind (localAddress、承诺);
  } 
  

调用的是pipeline.bind (xxx),管道我们知道,它链接了ChannelHandler的背景下,有头和tail.head是出站,尾巴是入站。

59. 网状的源代码分析-ServerBootstrap绑定过程2