NOTE

2.79 1.实例化channel

1. 要分析的代码 2. 反射调用Channel.class的构造方法创建实例 通过反射调用NioServerSocketChannel的构造方法 3. NioServerSocketChannel 3.1. 类体系 3.2. 构造方法 3.2.1. 创建JDK NIO底层的ServerSocket

Java创建于 更新于 historical

这是历史学习笔记,可能存在过时或不完整的理解。

1. 要分析的代码

//实例化channel
channel = channelFactory.newChannel();

2. 反射调用Channel.class的构造方法创建实例

public T newChannel() {
    try {
    	//通过反射调用NioServerSocketChannel的构造方法
        return clazz.getConstructor().newInstance();
    } catch (Throwable t) {
        throw new ChannelException("Unable to create Channel from class " + clazz, t);
    }
}

通过反射调用NioServerSocketChannel的构造方法

3. NioServerSocketChannel

3.1. 类体系

NioServerSocketChannel->ServerSocketChannel->ServerChannel->Channel

3.2. 构造方法

public NioServerSocketChannel() {
	//通过newSocket创建ServerSocketChannel--JDK NIO底层的类
	//provider.openServerSocketChannel()
	//接着调用构造方法
    this(newSocket(DEFAULT_SELECTOR_PROVIDER));
}

3.2.1. 创建JDK NIO底层的ServerSocketChannel

private static ServerSocketChannel newSocket(SelectorProvider provider) {
    try {

        return provider.openServerSocketChannel();
    } catch (IOException e) {
        throw new ChannelException(
                "Failed to open a server socket.", e);
    }
}

provider.openServerSocketChannel();最终new了一个ServerSocketChannelImpl,而ServerSocketChannelImpl extends ServerSocketChannel,是jdk底层的channel

3.2.2. 监听OP_ACCEPT事件

继续跟踪NioServerSocketChannel的构造方法


public NioServerSocketChannel(ServerSocketChannel channel) {
	//AbstractNioMessageChannel->AbstractNioChannel【√】->AbstractChannel【√】
	//传入的监听事件为SelectionKey.OP_ACCEPT
    super(null, channel, SelectionKey.OP_ACCEPT);
    //使用config类保存刚刚创建的NioServerSocketChannel和channel对应的ServerSocket
    //这个ServerSocketChannelConfig专门用于配置的
    config = new NioServerSocketChannelConfig(this, javaChannel().socket());
}

调用父类的构造并传入SelectionKey.OP_ACCEPT:监听事件 创建了一个ServerSocketChannelConfig用于配置options、attrs等属性

我们继续跟踪父类AbstractNioChannel的构造方法

3.2.3. 配置channel为非阻塞

  • AbstractNioChannel
protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
	//AbstractChannel构造
    super(parent);
    this.ch = ch;
    this.readInterestOp = readInterestOp;
    try {
    	//配置非阻塞
        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);
    }
}

这里配置selector的非阻塞,继续调用父类的构造

3.2.4. 创建channelId、Unsafe、pipeline

  • AbstractChannel
protected AbstractChannel(Channel parent) {
    this.parent = parent;
	//创建channelid
    id = newId();
    //创建unsafe
    unsafe = newUnsafe();
    //创建pipeline
    pipeline = newChannelPipeline();
}
3.2.4.1. 创建channelid

我们知道每个channel都有一个唯一的channelId,如下,可看出由machineId、processId、sequence、timestamp、random决定

private DefaultChannelId() {
    data = new byte[MACHINE_ID.length + PROCESS_ID_LEN + SEQUENCE_LEN + TIMESTAMP_LEN + RANDOM_LEN];
    int i = 0;

    // machineId
    System.arraycopy(MACHINE_ID, 0, data, i, MACHINE_ID.length);
    i += MACHINE_ID.length;

    // processId
    i = writeInt(i, PROCESS_ID);

    // sequence
    i = writeInt(i, nextSequence.getAndIncrement());

    // timestamp (kind of)
    i = writeLong(i, Long.reverse(System.nanoTime()) ^ System.currentTimeMillis());

    // random
    int random = PlatformDependent.threadLocalRandom().nextInt();
    i = writeInt(i, random);
    assert i == data.length;

    hashCode = Arrays.hashCode(data);
}
3.2.4.2. 创建unsafe

这个Unsafe其实封装的是JDK底层NIO包的操作,netty把他叫做unsafe

3.2.4.3. newChannelPipeline
protected DefaultChannelPipeline newChannelPipeline() {
	//创建的是DefaultChannelPipeline
    return new DefaultChannelPipeline(this);
}
3.2.4.3.1. ChannelPipeline类体系

其中ChannelOutboundInvoker定义了哪些Handler属于pipeline中的outbound,而ChannelInboundInvoker规定了哪些Handler属于pipeline中的inboud

ChannelOutboundInvoker
	bind
	connect
	connect
	disconnect
	close
	deregister
	bind
	connect
	connect
	disconnect
	close
	deregister
	read
	write
	write
	flush
	writeAndFlush
	writeAndFlush
	newPromise
	newProgressivePromise
	newSucceededFuture
	newFailedFuture
	voidPromise

ChannelInboundInvoker
	fireChannelRegistered
	fireChannelUnregistered
	fireChannelActive
	fireChannelInactive
	fireExceptionCaught
	fireUserEventTriggered
	fireChannelRead
	fireChannelReadComplete
	fireChannelWritabilityChanged
  • 构造方法
protected DefaultChannelPipeline(Channel channel) {
    this.channel = ObjectUtil.checkNotNull(channel, "channel");
    succeededFuture = new SucceededChannelFuture(channel, null);
    voidPromise =  new VoidChannelPromise(channel, true);

	//pipeline中的链表,每个元素时AbstractChannelHandlerContext,包装了Handler
    tail = new TailContext(this);
    head = new HeadContext(this);

    head.next = tail;
    tail.prev = head;
}

上面的TailContext属于ChannelInboundHandler,HeadContext属于ChannelOutboundHandler, ChannelInboundHandler。都继承了AbstractChannelHandlerContext,实现了一个双向链表的结构