Channel
Netty的抽象了一个顶层接口Channel相比原来NIO提供的Channel有更多的功能,当然也是相对复杂的。
Java NIO包下的channel
JavaNIO包下的channel 做了三层封装
- 最顶层的Channel只封装了关和开两种状态
- 第二层SelectableChannel封装了和Selector交互的状态
- 第三层封装了具体的业务类
Netty的channel
- 继承图
做了四层封装
-
第一层channel
抽象了所有的channel的公共行为
-
第二层channel
规定了channel为Nio的抽象
-
第三层channel
读写层的抽象 -
第四层channel 具体业务的实现,比如serverSocketChannel
AttributeMap
一个线程安全的map,附在channel或者ChannelHandlerContext上 Channel上的AttributeMap就是大家共享的,每一个ChannelHandler都能获取到
MyDefaultAttribute.java
AttributeMap可以看成是一个key为AttributeKey类型,value为Attribute类型的Map,而Attribute内存储的是一个值引用,它可以原子的更新内容,是线程安全的 pool常量池存放了key
public final class MyAttributeKey<T> extends AbstractConstant<MyAttributeKey<T>> {
private static final ConstantPool<MyAttributeKey<Object>> pool = new ConstantPool<MyAttributeKey<Object>>() {
@Override
protected MyAttributeKey<Object> newConstant(int id, String name) {
return new MyAttributeKey<>(id, name);
}
};
}
AttributeMap接口的默认实现类是DefaultAttributeMap类,该类有一个内部类DefaultAttribute,实现了Attribute接口,其定义如下:
private static final class MyDefaultAttribute<T> extends AtomicReference<T> implements MyAttribute<T> {
private static final long serialVersionUID = 4618134439190501308L;
private static final AtomicReferenceFieldUpdater<MyDefaultAttribute, MyDefaultAttributeMap> MAP_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(MyDefaultAttribute.class,
MyDefaultAttributeMap.class, "attributeMap");
private final MyAttributeKey<T> key;
private volatile MyDefaultAttributeMap attributeMap;
MyDefaultAttribute(MyDefaultAttributeMap attributeMap, MyAttributeKey<T> key) {
this.attributeMap = attributeMap;
this.key = key;
}
@Override
public MyAttributeKey<T> key() {
return key;
}
@Override
public T setIfAbsent(T value) {
while (!compareAndSet(null, value)) {
T old = get();
if (old != null) {
return old;
}
}
return null;
}
@Override
public T getAndRemove() {
MyDefaultAttributeMap attributeMap = this.attributeMap;
boolean removed = attributeMap != null && MAP_UPDATER.compareAndSet(this, attributeMap, null);
T oldValue = getAndSet(null);
if (removed) {
attributeMap.removeAttributeIfMatch(key, this);
}
return oldValue;
}
@Override
public void remove() {
final MyDefaultAttributeMap attributeMap = this.attributeMap;
final boolean removed = attributeMap != null && MAP_UPDATER.compareAndSet(this, attributeMap, null);
set(null);
if (removed) {
attributeMap.removeAttributeIfMatch(key, this);
}
}
private boolean isRemoved() {
return attributeMap == null;
}
}
该类继承了AtomicReference类,这是Netty内部实现的一个原子引用类,因此DefaultAttribute是线程安全的。它是一个双向链表的节点,也就是所有的Attribute连接成了一个双向链表的存储结构。而DefaultAttribute对象被存放在了一个AtomicReferenceArray类型的数组结构的属性attributes里面,这是AttributeMap内部的核心存储结构。
Netty启动的时候怎么创建channel
创建channelfactory
ServerBootStrap.channel 返回一个serverbootstrap, 提交一个channel类
class Test {
public B channel(Class<? extends C> channelClass) {
return channelFactory(new ReflectiveChannelFactory<C>(
ObjectUtil.checkNotNull(channelClass, "channelClass")
));
}
}
反射加载: 获取到类的加载器,构建一个channelfactory返回到abstractBootStrap中
class Test {
public ReflectiveChannelFactory(Class<