五Netty源码分析--3Bootstrap.bind--上

五Netty源码分析--3Bootstrap.bind--上

第三节 ServerBootstrap.bind()源码解析

3.1 ServerBootstrap配置方法

首先从ServerBootstrap的配置方法跟入,看如何实现

image-20221202093930633

TAG0.1 parent属性设置

group传入,分别设置parentgroup和childgroup。

ServerBootstrap

    public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
        super.group(parentGroup);
        ObjectUtil.checkNotNull(childGroup, "childGroup");
        if (this.childGroup != null) {
            throw new IllegalStateException("childGroup set already");
        }
        this.childGroup = childGroup;
        return this;
    }

AbstractBootstrap
   public B group(EventLoopGroup group) {
        ObjectUtil.checkNotNull(group, "group");
        if (this.group != null) {
            throw new IllegalStateException("group set already");
        }
        this.group = group;
        return self();
    }

跟入channel()方法,

  AbstractBootstrap
  
    public B channel(Class<? extends C> channelClass) {
    //传入反射创建channel的工厂类ReflectiveChannelFactory
        return channelFactory(new ReflectiveChannelFactory<C>(
                ObjectUtil.checkNotNull(channelClass, "channelClass")
        ));
    }

    public B channelFactory(io.netty.channel.ChannelFactory<? extends C> channelFactory) {
        return channelFactory((ChannelFactory<C>) channelFactory);
    }

   @Deprecated
    public B channelFactory(ChannelFactory<? extends C> channelFactory) {
        ObjectUtil.checkNotNull(channelFactory, "channelFactory");
        if (this.channelFactory != null) {
            throw new IllegalStateException("channelFactory set already");
        }
				//设置创建channel的反射工厂类
        this.channelFactory = channelFactory;
        return self();
    }

根据channel传入的class类型,来反射创建channel实例的reflective工厂类

public class ReflectiveChannelFactory<T extends Channel> implements ChannelFactory<T> {

    private final Class<? extends T> clazz;

    public ReflectiveChannelFactory(Class<? extends T> clazz) {
        if (clazz == null) {
            throw new NullPointerException("clazz");
        }
        this.clazz = clazz;
    }

    @Override
    public T newChannel() {
        try {
          //反射创建channel对应的实例
            return clazz.newInstance();
        } catch (Throwable t) {
            throw new ChannelException("Unable to create Channel from class " + clazz, t);
        }
    }

然后,跟入设置ChannelHandler的方法:

AbstractBootstrap //父类中
//设置parent的handler
    public B handler(ChannelHandler handler) {
        this.handler = ObjectUtil.checkNotNull(handler, "handler");
        return self();
    }
TAG0.2 Child属性设置
ServerBootstrap
  //设置server端启动类中的childHandler
    public ServerBootstrap childHandler(ChannelHandler childHandler) {
        this.childHandler = ObjectUtil.checkNotNull(childHandler, "childHandler");
        return this;
    }

区别:handler与childHandler

父类中的handler是客户端新接入的连接socketChannel对应的pipeline上的handler,因此是个工厂类,为每个新接入的客户端都创建一个新的handler。(该handler,用于在accept之前,父类给每个接入的channel,所加入的handler

启动辅助类ServerBootstrap设置childhandler是NioServerSocketChannel对应的channelPipeline上的handler,所有连接该监听端口的客户端socketchannel都会执行该handler处理器;(该handler,用于accpet成功后,执行IO操作时,会链式处理的handler

因此,两者的加入时机和处理阶段不同,如下图理解区别。

image-20221006231020474

3.2 serverBootstrap.bind()方法

从如下位置跟入源码:

image-20221202103707572

AbstractBootstrap
//bind作用:创建新的channel,并且绑定
    public ChannelFuture bind(String inetHost, int inetPort) {
        return bind(SocketUtils.socketAddress(inetHost, inetPort));
    }

 public ChannelFuture bind(SocketAddress localAddress) {
   			//验证group与channelFactory是否为null
        validate();
        return doBind(ObjectUtil.checkNotNull(localAddress, "localAddress"));
    }


    private ChannelFuture doBind(final SocketAddress localAddress) { //1 
//TAG1 initAndRegister() 
      //创建并初始化serversocketchannel,将其注册到nioeventloop的selector,返回异步结果channelFuture
       final ChannelFuture regFuture = initAndRegister();
//TAG2 ChannelFuture.channel
      //从channelFuture获取新创建的channel
        final Channel channel = regFuture.channel();
        if (regFuture.cause() != null) {
            return regFuture;
        }
			
      //异步操作有结果
        if (regFuture.isDone()) { //2 
            // At this point we know that the registration was complete and successful.
            ChannelPromise promise = channel.newPromise();
//TAG3 doBind0() 绑定指定的端口
            doBind0(regFuture, channel, localAddress, promise);
            return promise;
        } else { //2 
//TAG4 channelfuture异步机制
           //异步操作尚未有结果(异步编程技巧)
            final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel);
          //针对异步操作没有结果的情况,可以为future.addlistener,实现该监听器操作完成时的方法定义,在异步操作完成后,继续进行后续的逻辑
            regFuture.addListener(new ChannelFutureListener() { //3 
                @Override
              //异步操作完成时,的listener逻辑
                public void operationComplete(ChannelFuture future) throws Exception { //4
                    Throwable cause = future.cause();
                    if (cause != null) {
                        promise.setFailure(cause);
                    } else {
                        promise.executor = channel.eventLoop();
                    }
                  //监听channelfuture的异步操作结果完成后,继续原来逻辑操作doBind0
                    doBind0(regFuture, channel, localAddress, promise);
                } //4 
            }); //3 
            return promise;
        } //2
      
    } //1 

作图梳理doBind()的绑定操作逻辑:

dobind流程逻辑:
	1 首先通过initAndRegister()方法,创建并初始化serverSocketChannel、注册到eventLoop的selector上,然后获取到channelFuture异步操作结果。
	2 ChannelFuture.isDone()
		2.1 如果异步操作有结果,根据操作获取channel,然后执行doBind0,bind该channel端口;
		2.2 如果异步操作channelFuture没有结果,则通过添加listener监听,在异步操作完成时,doBind0,继续执行bind的逻辑操作。

这里针对异步操作future的编程技巧,[详见此处](# 4 future异步编程技巧(todo))

下面继续跟进bind的两大方法。

TAG1 initAndRegister()
AbstractBootstrap   
final ChannelFuture initAndRegister() {
 //TAG1.1 反射创建NioServerSocketChannel
        final Channel channel = channelFactory().newChannel();
        try {
 //TAG1.2 初始化channel
            init(channel);
        } catch (Throwable t) {
 						if (channel != null) {
                // channel can be null if newChannel crashed (eg SocketException("too many open files"))
                channel.unsafe().closeForcibly();
                return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
            }
            // as the Channel is not registered yet we need to force the usage of the GlobalEventExecutor
            return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
        }

 //TAG1.3 注册channel到selector
        ChannelFuture regFuture = group().register(channel);
        if (regFuture.cause() != null) {
            if (channel.isRegistered()) {
                channel.close();
            } else {
                channel.unsafe().closeForcibly();
            }
        }

        // If we are here and the promise is not failed, it's one of the following cases:
        // 1) If we attempted registration from the event loop, the registration has been completed at this point.
        //    i.e. It's safe to attempt bind() or connect() now because the channel has been registered.
        // 2) If we attempted registration from the other thread, the registration request has been successfully
        //    added to the event loop's task queue for later execution.
        //    i.e. It's safe to attempt bind() or connect() now:
        //         because bind() or connect() will be executed *after* the scheduled registration task is executed
        //         because register(), bind(), and connect() are all bound to the same thread.

        return regFuture;
    }

该处代码,此处initAndRegister()主要做三部分操作:

 //TAG1 反射创建NioServerSocketChannel
        final Channel channel = channelFactory().newChannel();
        
 //TAG2 初始化channel
        init(channel);
            
 //TAG3 注册channel到selector
        ChannelFuture regFuture = group().register(channel);
TAG1.1 channelFactory().newChannel()--父channel创建
AbstractBootstrap
		//返回channel工厂类
    final ChannelFactory<? extends C> channelFactory() {
        return channelFactory;
    }

image-20221007121638186

可知,当前工厂类,为serverbootstrap设置channel属性时,创建的reflectiveChannelFactory反射工厂。

然后,跟入newChannel()

   ReflectiveChannelFactory
   @Override
    public T newChannel() {
        try {
          	//根据clazz类,反射方法,调用无参构造函数创建NioServerSocketChannel
            return clazz.newInstance();
        } catch (Throwable t) {
            throw new ChannelException("Unable to create Channel from class " + clazz, t);
        }
    }

在ServerBootstrap端传入的channel类为NioServerSocketChannel.class;此处clazz.newInstance(),调用channel类的无参构造。

public class NioServerSocketChannel extends AbstractNioMessageChannel
                             implements io.netty.channel.socket.ServerSocketChannel {
//TAG1.1.1 SelectorProvider.provider
		//静态变量初始化,jvm中单例的provider实例,用来创建selector和原生channel
    private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider();

      public NioServerSocketChannel() {
//TAG1.1.2 newSocket(DEFAULT_SELECTOR_PROVIDER)
//TAG1.1.3 NioServerSocketChannel(ServerSocketChannel)
        this(newSocket(DEFAULT_SELECTOR_PROVIDER));
    }
  
  private static ServerSocketChannel newSocket(SelectorProvider provider) {
        try {
          //使用provider创建NIO原生serverSocketChannel
            return provider.openServerSocketChannel();
        } catch (IOException e) {
            throw new ChannelException(
                    "Failed to open a server socket.", e);
        }
    }
  
      public NioServerSocketChannel(ServerSocketChannel channel) {
//TAG1.1.4 super(null, channel, SelectionKey.OP_ACCEPT)--Nettychannel注册
        //第一个参数是父channel(server端channel,父channel为null)
        //channel是NIO原生channel,accept是设置当前serversocketchannel关注事件为接受连接(server端为accept)
        super(null, channel, SelectionKey.OP_ACCEPT);
        config = new NioServerSocketChannelConfig(this, javaChannel().socket());
    }
TAG1.1.1 SelectorProvider.provider

image-20221202112613357

static final静态变量,会在构造函数执行前执行

SelectorProvider
    public static SelectorProvider provider() {
        synchronized (lock) {
            if (provider != null)
                return provider;
            return AccessController.doPrivileged(
                new PrivilegedAction<SelectorProvider>() {
                    public SelectorProvider run() {
                            if (loadProviderFromProperty())
                                return provider;
                            if (loadProviderAsService())
                                return provider;
                            provider = sun.nio.ch.DefaultSelectorProvider.create();
                            return provider;
                        }
                    });
        }
    }

这里SelectorProvider.provider()返回的是KQueueSelectorProvider对象。

image-20221202113340101

TAG1.1.1.1 KQueueSelectorProvider

当前类是JDK的nio.ch下的类

package sun.nio.ch;

public class KQueueSelectorProvider extends SelectorProviderImpl {
    public KQueueSelectorProvider() {
    }

  	//获取selector选择器实例
    public AbstractSelector openSelector() throws IOException {
        return new KQueueSelectorImpl(this);
    }
}

KQueueSelectorImpl

TAG1.1.2 newSocket(DEFAULT_SELECTOR_PROVIDER)
    NioServerSocketChannel
    private static ServerSocketChannel newSocket(SelectorProvider provider) {
        try {
//TAG1.1.2.1 provider.openServerSocketChannel
          //通过SelectorProvider创建ServerSocketChannel
            return provider.openServerSocketChannel();
        } catch (IOException e) {
            throw new ChannelException(
                    "Failed to open a server socket.", e);
        }
    }
TAG1.1.2.1 provider.openServerSocketChannel--原生channel
   public abstract class SelectorProviderImpl extends SelectorProvider {

   public ServerSocketChannel openServerSocketChannel() throws IOException {
     		//创建NIO原生channel类
        return new ServerSocketChannelImpl(this);
    }
package sun.nio.ch; //JDK原生ServerSocketChannelImpl

class ServerSocketChannelImpl extends ServerSocketChannel implements SelChImpl {

    ServerSocketChannelImpl(SelectorProvider var1) throws IOException {
        super(var1);
        this.fd = Net.serverSocket(true);
        this.fdVal = IOUtil.fdVal(this.fd);
        this.state = 0;
    }
  
     protected ServerSocketChannel(SelectorProvider provider) {
        super(provider);
    }
  
      protected AbstractSelectableChannel(SelectorProvider provider) {
        this.provider = provider;
    }

当前provider为KQueueSelectorProvider

image-20221202115011895

TAG1.1.3 NioServerSocketChannel(ServerSocketChannel)--原生Netty的channel

image-20221202115442230

可知此处newSocket创建出的是原生ServerSocketChannel的实现类impl。

这里使用原生ServerSocketChannel创建Netty的NioServerSocketChannel。

NioServerSocketChannel

    public NioServerSocketChannel(ServerSocketChannel channel) {
//TAG1.1.3.1
  			//第一个参数为parent channel,第二个参数channel为JDK原生serversocketchannel,第三个为当前channel所关注事件-ACCEPT
        super(null, channel, SelectionKey.OP_ACCEPT);
//TAG1.1.3.2 NioServerSocketChannelConfig
        config = new NioServerSocketChannelConfig(this, javaChannel().socket());
    }
TAG1.1.3.1 AbstractNioChannel(Netty创建)

调用父类构造super时,设置关注事件为accept,此处是[位运算的编程技巧](#2 位运算(todo))

看到selectionKey中设置的事件的标志位,通过位运算设置的。

    SelectionKey
    
    public static final int OP_READ = 1 << 0;   //read为1
    public static final int OP_WRITE = 1 << 2;  //write位4
    public static final int OP_CONNECT = 1 << 3;  //connect为8
    public static final int OP_ACCEPT = 1 << 4;  //accept为16

然后,跟入super父类

public abstract class AbstractNioMessageChannel extends AbstractNioChannel {

    protected AbstractNioMessageChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
        super(parent, ch, readInterestOp);
    }
package io.netty.channel.nio; //netty的channel
  
public abstract class AbstractNioChannel extends AbstractChannel {
  
      protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
//TAG1.1.3.1.1
        //调用父类super构造函数
        super(parent);
        //该处ch为NIO原生channel
        this.ch = ch;
        //设置channel关注的事件类型
        this.readInterestOp = readInterestOp;
        try {
          //设置当前channel非阻塞模式
            ch.configureBlocking(false);
        } catch (IOException e) {
            try {
                ch.close();
            } catch (IOException e2) {
                if (logger.isWarnEnabled()) {
                    logger.warn(
                            "Failed to close a partially initialized socket.", e2);
                }
            }

            throw new ChannelException("Failed to enter non-blocking mode.", e);
        }
    }

该处构造函数中,完成如下任务:

调用父类super构造函数;将原生的NIO的serverSockerChannel设置NioServerSocketChannel;设置当前channel的关注事件readInterestOp为ACCPEPT;最后设置阻塞类型为非阻塞。

TAG1.1.3.1.1 AbstractChannel(创建channelpipeline)

继续跟入父类构造函数

 protected AbstractChannel(Channel parent) {
        this.parent = parent;
          //设置channel唯一ID
        id = DefaultChannelId.newInstance();
          //在抽象channel中创建unsafe内部类
        unsafe = newUnsafe();
          //channel对应的pipeline在此处被创建(该pipeline与channel绑定)
        pipeline = new DefaultChannelPipeline(this);
    }

该处完成如下几个任务:
设置channel唯一ID,创建channel的底层操作类unsafe;创建与channel绑定的pipeline。

TAG1.1.3.2 NioServerSocketChannelConfig
  public NioServerSocketChannel(ServerSocketChannel channel) {
        super(null, channel, SelectionKey.OP_ACCEPT);

        config = new NioServerSocketChannelConfig(this, javaChannel().socket());
    }

此处,是netty的channel实例化过程中,创建config配置类,保存当前channel的属性。

1 javaChannel().socket()

NioServerSocketChannel
    protected ServerSocketChannel javaChannel() {
        return (ServerSocketChannel) super.javaChannel();
    }

AbstractNioChannel
    protected SelectableChannel javaChannel() {
        return ch;
    }

image-20221202122149085

返回前面创建的Java原生ServerSocketChannelImpl对象。

class ServerSocketChannelImpl extends ServerSocketChannel implements SelChImpl {

  //ServerSocketChannelImpl.socket()创建适配器类,把NIO原生ServerSocketChannelImpl的操作,交给adapter实现
   public ServerSocket socket() {
        synchronized(this.stateLock) {
            if (this.socket == null) {
                this.socket = ServerSocketAdaptor.create(this);
            }

            return this.socket;
        }
    }

2 NioServerSocketChannel.NioServerSocketChannelConfig(内部类)

image-20221202123042591

image-20221202123101027

config是NioServerSocketChannel的内部类

    public DefaultServerSocketChannelConfig(ServerSocketChannel channel, ServerSocket javaSocket) {
        super(channel);
        if (javaSocket == null) {
            throw new NullPointerException("javaSocket");
        }
        this.javaSocket = javaSocket;
    }
TAG1.1.4 super(null, channel, SelectionKey.OP_ACCEPT)--Nettychannel初始化并注册
NioServerSocketChannel

      public NioServerSocketChannel(ServerSocketChannel channel) {
//TAG1.1.4 super(null, channel, SelectionKey.OP_ACCEPT)--Nettychannel注册
        //第一个参数是父channel(server端channel,父channel为null)
        //channel是NIO原生channel,accept是设置当前serversocketchannel关注事件为接受连接(server端为accept)
        super(null, channel, SelectionKey.OP_ACCEPT);
        config = new NioServerSocketChannelConfig(this, javaChannel().socket());
    }

在NioServerSocketChannel实例化时候,设置Netty的channel关注事件为OP_ACCEPT

image-20221206161244120
public abstract class AbstractNioMessageChannel extends AbstractNioChannel {
    boolean inputShutdown;

    protected AbstractNioMessageChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
        super(parent, ch, readInterestOp);
    }
public abstract class AbstractNioChannel extends AbstractChannel {

    private final SelectableChannel ch; //Netty的NioServerSocketChannel绑定的NIO原生serversocketchannel
    protected final int readInterestOp; //设置NioServerSocketChannel关注的事件
    volatile SelectionKey selectionKey;
    boolean readPending;

    protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
        super(parent);
        this.ch = ch;
        this.readInterestOp = readInterestOp; //初始化时,设置NioServerSocketChannel关注事件为OP_ACCEPT
        try {
            ch.configureBlocking(false); //设置Netty为非阻塞
        } catch (IOException e) {
            try {
                ch.close();
            } catch (IOException e2) {
                logger.warn(
                            "Failed to close a partially initialized socket.", e2);
            }

            throw new ChannelException("Failed to enter non-blocking mode.", e);
        }
    }

Netty的NioServerSocketChannel在初始化过程中,持有NIO原生channel,并设置server端channel关注的事件为OP_ACCEPT接受连接。

TAG1.2:init(channel)--初始化Netty的channel
AbstractBootstrap
//TAG1
    final ChannelFuture initAndRegister() {
        Channel channel = null;
        try {
//TAG1.1
            channel = channelFactory.newChannel();
//TAG1.2
            init(channel);
        }

image-20221202134951216

然后回到initAndRegister()的主流程中,继续跟踪init(channel)。

ServerBootstrap

      @Override
    void init(Channel channel) {
/**………………………………………………………………………………设置serverbootstrap中parent属性到channel………………………………………………………………………………………… */
        setChannelOptions(channel, options0().entrySet().toArray(newOptionArray(0)), logger);
        setAttributes(channel, attrs0().entrySet().toArray(newAttrArray(0)));
			//获取NioServerSocketChannel绑定的pipeline
        ChannelPipeline p = channel.pipeline();

/**………………………………………………………………………………获取serverbootstrap中child属性option、attr………………………………………………………………………………………… */
  //child相关属性,是连接入server后创建的NioSocketChannel对应的属性
        final EventLoopGroup currentChildGroup = childGroup;
        final ChannelHandler currentChildHandler = childHandler;
  			//获取serverbootstrap上的option、attr属性
        final Entry<ChannelOption<?>, Object>[] currentChildOptions =
                childOptions.entrySet().toArray(newOptionArray(0));
        final Entry<AttributeKey<?>, Object>[] currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(0));
  
//TAG1.2.1 ChannelPipeline.addLast
				//pipeline中添加自定义ChannelInitializer(该channelInitializer添加入pipeline,在完成channe初始化后,自动从pipeline中移除
        p.addLast(new ChannelInitializer<Channel>() {
            @Override
            public void initChannel(final Channel ch) {
                final ChannelPipeline pipeline = ch.pipeline();
                ChannelHandler handler = config.handler();
                if (handler != null) {
                    pipeline.addLast(handler);
                }

                ch.eventLoop().execute(new Runnable() {
                    @Override
                    public void run() {
//TAG1.2.2 ServerBootstrapAcceptor
               //为ServerSocketChannel的pipeline中添加ServerBootstrapAcceptor处理器
              //该处理器用来把childChannel的属性,添加入serversocketchannel.accpet生成的socketchannel的属性中
                        pipeline.addLast(new ServerBootstrapAcceptor(
                                ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
                    }
                });
            }
        });
    }

这里,init()主要完成属性的设置,分别为父属性和child属性的获取和设置。

父属性是serverbootstrap通过option、attr设置的,获取后设置入serversocketchannel中;

child属性,也是通过serverbootstrap通过childoption、childattr设置入,获取后,通过为serversocketchannel.pipeling添加ServerBootstrapAcceptor的ChannelInitializer处理器,其内为child的所有属性,负责为接入后的socketchannel设置child属性。

注意:

这里没有将serverbootstrap中handler加入pipeline中

image-20221202131249293

着重分析如下流程:

//TAG1.2.1 ChannelPipeline.addLast
				//pipeline中添加自定义ChannelInitializer(该channelInitializer添加入pipeline,在完成channe初始化后,自动从pipeline中移除
        p.addLast(new ChannelInitializer<Channel>() {
            @Override
            public void initChannel(final Channel ch) {
                final ChannelPipeline pipeline = ch.pipeline();
                ChannelHandler handler = config.handler();
                if (handler != null) {
                    pipeline.addLast(handler);
                }

                ch.eventLoop().execute(new Runnable() {
                    @Override
                    public void run() {
//TAG1.2.2 ServerBootstrapAcceptor
               //为ServerSocketChannel的pipeline中添加ServerBootstrapAcceptor处理器
              //该处理器用来把childChannel的属性,添加入serversocketchannel.accpet生成的socketchannel的属性中
                        pipeline.addLast(new ServerBootstrapAcceptor(
                                ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
                    }
                });
            }
        });
    }
TAG1.2.1 ChannelPipeline.addLast
DefaultChannelPipeline
    @Override
    public final ChannelPipeline addLast(ChannelHandler... handlers) {
        return addLast(null, handlers);
    }
    
        @Override
    public final ChannelPipeline addLast(EventExecutorGroup executor, ChannelHandler... handlers) {
        if (handlers == null) {
            throw new NullPointerException("handlers");
        }
			
      	//遍历handlers,并包装为context加入pipeline中
        for (ChannelHandler h: handlers) {
            if (h == null) {
                break;
            }
            addLast(executor, null, h);
        }

        return this;
    }

    @Override
    public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
        final AbstractChannelHandlerContext newCtx;
        synchronized (this) { //1
            checkMultiplicity(handler);
						//由handler创建AbstractChannelHandlerContext
            newCtx = newContext(group, filterName(name, handler), handler);
						//加入pipeline中
            addLast0(newCtx);

/**————————————————————————————————channelHandler.handlerAdded逻辑—————————————————————————————————————————————— */
//server端,启动时,第一次执行,执行这里
          	//register为false--表示channel尚未在eventloop上注册
            if (!registered) {
              	//设置新创建的context状态为ADDPENDING
                newCtx.setAddPending();
//TAG1.2.1.1 callHandlerCallbackLater
    //将newCtx加入pipeline,并将newCtx加入HandlerCallbackLater的task任务中,一旦channel注册,就执行ChannelHandler.handlerAdded
                callHandlerCallbackLater(newCtx, true);
                return this;
            }
					
            EventExecutor executor = newCtx.executor();
//TAG1.2.1.2 callHandlerAddedInEventLoop
          	//在eventloop的线程中执行callHandlerAdded0---调用handleradd方法
            if (!executor.inEventLoop()) {
                callHandlerAddedInEventLoop(newCtx, executor);
                return this;
            }
        } //1
//TAG1.2.1.3 callHandlerAdded0
      	//如果当前线程是eventloop,直接执行callHandlerAdded0
        callHandlerAdded0(newCtx);
        return this;
    }

//加入pipeline尾,tail之前
    private void addLast0(AbstractChannelHandlerContext newCtx) {
        AbstractChannelHandlerContext prev = tail.prev;
        newCtx.prev = prev;
        newCtx.next = tail;
        prev.next = newCtx;
        tail.prev = newCtx;
    }

这里加入了ChannelInitializer类,该channelInitializer添加入pipeline,在完成channe初始化后,自动从pipeline中移除。

ChannelPipeline.addLast(handler)逻辑:

pipeline中add(handler)逻辑:
synchronized (pipeline) {
  1 handler--》创建对应的context对象,并将context加入pipeline的handlercontext的处理链中;
  2 如果channel是否注册在nioeventloop上
    2.1 如果没有注册:
    			将ctx设置为ADDPENDING状态,
//TAG1.2.1.1 callHandlerCallbackLater,将当前newCtx加入HandlerCallbackLater的task任务中,一旦channel注册,就执行ChannelHandler.handlerAdded
    2.2 如果注册过
       2.2.1 当前线程不是eventloop中线程
//TAG1.2.1.2 callHandlerAddedInEventLoop   在eventloop.executor.execute()中执行callHandlerAdded0--执行handler.add操作
}
3 如果当前线程是eventloop绑定的,那么操作pipeline是线程安全,不在synchronized (pipeline)中执行
  直接//TAG1.2.1.3 callHandlerAdded0,执行handler.add操作
//TAG1.2.1.1 callHandlerCallbackLater(server端开启,只执行这里)
AbstractChannelHandlerContext

    final void setAddPending() {
  			//设置context的状态为ADD_PENDING,代表当前context需要执行handler.add操作
        boolean updated = HANDLER_STATE_UPDATER.compareAndSet(this, INIT, ADD_PENDING); 
        assert updated; 
    }
DefaultChannelPipeline
	//added为true
   private void callHandlerCallbackLater(AbstractChannelHandlerContext ctx, boolean added) {
        assert !registered;
				//将加入pipeline的handlercontext,创建并包装为PendingHandlerAddedTask--待执行handlerAdd操作的task
        PendingHandlerCallback task = added ? new PendingHandlerAddedTask(ctx) : new PendingHandlerRemovedTask(ctx);
  			//获取需要执行handler.add操作任务的,列表的head(PendingHandlerCallback链的head)
        PendingHandlerCallback pending = pendingHandlerCallbackHead;
        if (pending == null) {
          	//如果head为null,直接将head设置为当前新创建的task
            pendingHandlerCallbackHead = task;
        } else {
            // 找到pendingTask的尾部
            while (pending.next != null) {
                pending = pending.next;
            }
          	//将新创建的task,加入PendingHandlerCallback链尾部
            pending.next = task;
        }
    }

这里逻辑是,在channel尚未注册到nioeventloop时,将handler--》handlercontext加入pipeline后,将context包装成PendingHandlerAddedTask,并加入pipeline的task链尾部。当channel一旦注册到nioeventloop上,就执行pendingtask上的handler.add操作。

image-20221207134908177

这里,task包裹ctx对应的channelhandler为:

image-20230310163906570
//TAG1.2.1.2 callHandlerAddedInEventLoop(跳过)
DefaultChannelPipeline

    private void callHandlerAddedInEventLoop(final AbstractChannelHandlerContext newCtx, EventExecutor executor) {
        newCtx.setAddPending();
        	//在nioeventloop所在线程中,执行callHandlerAdded0---调用handler.added操作
        executor.execute(new Runnable() {
            @Override
            public void run() {
              //TAG1.2.1.3 callHandlerAdded0
                callHandlerAdded0(newCtx);
            }
        });
    }
//TAG1.2.1.3 callHandlerAdded0(跳过)
DefaultChannelPipeline

 private void callHandlerAdded0(final AbstractChannelHandlerContext ctx) {
        try {
//TAG1.2.1.3.1 handlerContext.callHandlerAdded
          	//调用handlercontext的handleradd操作
            ctx.callHandlerAdded();
        } catch (Throwable t) {
            boolean removed = false;
            try {
                atomicRemoveFromHandlerList(ctx);
                ctx.callHandlerRemoved();
                removed = true;
            } catch (Throwable t2) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Failed to remove a handler: " + ctx.name(), t2);
                }
            }

            if (removed) {
                fireExceptionCaught(new ChannelPipelineException(
                        ctx.handler().getClass().getName() +
                        ".handlerAdded() has thrown an exception; removed.", t));
            } else {
                fireExceptionCaught(new ChannelPipelineException(
                        ctx.handler().getClass().getName() +
                        ".handlerAdded() has thrown an exception; also failed to remove.", t));
            }
        }
    }
//TAG1.2.1.3.1 handlerContext.callHandlerAdded(跳过)
AbstractChannelHandlerContext

    final void callHandlerAdded() throws Exception {
  			//首先设置handlerContext的状态为ADD-COMPLETE
        if (setAddComplete()) {
//HanAdd1 handler().handlerAdded(this)
            handler().handlerAdded(this);
        }
    }

    final boolean setAddComplete() {
        for (;;) {
            int oldState = handlerState;
            if (oldState == REMOVE_COMPLETE) {
                return false;
            }
            // 设置状态为ADD_COMPLETE
            if (HANDLER_STATE_UPDATER.compareAndSet(this, oldState, ADD_COMPLETE)) {
                return true;
            }
        }
    }
//HanAdd1 handler().handlerAdded(this)(调用handler.handlerAdded)--channelInitializer的执行(跳过)
public interface ChannelHandler {

    /**
     * Gets called after the {@link ChannelHandler} was added to the actual context and it's ready to handle events.
     */
    void handlerAdded(ChannelHandlerContext ctx) throws Exception;

当handler被真正添加入handlerContext后,会调用channelHandler.handlerAdded操作,之后,handler才能真正的准备好处理事件。

对于ChannelInitializer实现类来说:

ChannelInitializer
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        if (ctx.channel().isRegistered()) {
//HanADD1.1 ChannelInitializer.initChannel
            //初始化channel---channelInitializer类的initChannel方法,会将childhandler添加入channelPipeline中
            if (initChannel(ctx)) {
//HanAdd1.2 removeState---略
                // We are done with init the Channel, removing the initializer now.
                removeState(ctx);
            }
        }
    }
//HanADD1.1 ChannelInitializer.initChannel(跳过)
ChannelInitializer
    private boolean initChannel(ChannelHandlerContext ctx) throws Exception {
        if (initMap.add(ctx)) { // Guard against re-entrance.
            try {
//HanADD1.1.1 initChannel((C) ctx.channel())
                initChannel((C) ctx.channel());
            } catch (Throwable cause) {
                // Explicitly call exceptionCaught(...) as we removed the handler before calling initChannel(...).
                // We do so to prevent multiple calls to initChannel(...).
                exceptionCaught(ctx, cause);
            } finally {
                ChannelPipeline pipeline = ctx.pipeline();
                if (pipeline.context(this) != null) {
//HanAdd1.1.2 pipeline.remove(channelInitializer)
                  //将ChannelInitializer从pipeline中移除
                    pipeline.remove(this);
                }
            }
            return true;
        }
        return false;
    }
//HanADD1.1.1 initChannel((C) ctx.channel())--(跳过)

ctx.channel为handlerContext所绑定的channel。

image-20230310163951712

这里,initChannel方法会执行ServerBootstrap中创建匿名类ServerBootstrap$1的initChannel方法。

该执行过程,会向pipeline中添加ServerBootstrapAcceptor类,其中currentChildHandler为Server启动程序中,添加的自定义channelInitializer类

image-20221207131138025
//HanAdd1.1.2 pipeline.remove(channelInitializer)--略
DefaultChannelPipeline
    @Override
    public final ChannelPipeline remove(ChannelHandler handler) {
        remove(getContextOrDie(handler));
        return this;
    }
    
    public final ChannelPipeline remove(ChannelHandler handler) {
        remove(getContextOrDie(handler));
        return this;
    }
    
        private AbstractChannelHandlerContext remove(final AbstractChannelHandlerContext ctx) {
        assert ctx != head && ctx != tail;

        synchronized (this) {
            atomicRemoveFromHandlerList(ctx);

            // If the registered is false it means that the channel was not registered on an eventloop yet.
            // In this case we remove the context from the pipeline and add a task that will call
            // ChannelHandler.handlerRemoved(...) once the channel is registered.
            if (!registered) {
                callHandlerCallbackLater(ctx, false);
                return ctx;
            }

            EventExecutor executor = ctx.executor();
            if (!executor.inEventLoop()) {
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        callHandlerRemoved0(ctx);
                    }
                });
                return ctx;
            }
        }
        callHandlerRemoved0(ctx);
        return ctx;
    }

这个逻辑,同TAG1.2.1 ChannelPipeline.addLast逻辑相同,省略

posted @ 2023-03-10 17:26  LeasonXue  阅读(105)  评论(0编辑  收藏  举报