NOTE
2.79 1.实例化channel
1. 要分析的代码 2. 反射调用Channel.class的构造方法创建实例 通过反射调用NioServerSocketChannel的构造方法 3. NioServerSocketChannel 3.1. 类体系 3.2. 构造方法 3.2.1. 创建JDK NIO底层的ServerSocket
这是历史学习笔记,可能存在过时或不完整的理解。
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,实现了一个双向链表的结构
