netty之AttributeMap

这几天开始看netty,作些笔记。
netty5文档中 ChannelHandler开始处介绍了attachment的使用,用来保存handler的状态信息


public class DataServerHandler extends SimpleChannelInboundHandler {
private final AttributeKey auth =
new AttributeKey("auth");

@Override
public void channelRead(ChannelHandlerContext ctx, Integer integer) {
Attribute attr = ctx.getAttr(auth);
//...
}

AttributeKey和Attribute应该就是map中的键值对,而这个map应该绑定在ChannelHandlerContext中。

文档中对ChannelHandlerContext的描述:
A ChannelHandler is provided with a ChannelHandlerContext object. A ChannelHandler is supposed to interact with the ChannelPipeline it belongs to via a context object. Using the context object, the ChannelHandler can pass events upstream or downstream, modify the pipeline dynamically, or store the information (attachment) which is specific to the handler.

一个handler有一个与之对应的context,handler通过这个context对象与pipeline互动,
使用这个上下文对象,可以实现...保存某个handler的信息(attachment)。

查看源码:
DefaultChannelHandlerContext继承了DefaultAttributeMap

final class DefaultChannelHandlerContext extends DefaultAttributeMap implements ChannelHandlerContext{...}

DefaultAttributeMap的实现:

@SuppressWarnings("rawtypes")
private static final AtomicReferenceFieldUpdater updater = AtomicReferenceFieldUpdater.newUpdater(DefaultAttributeMap.class, Map.class, "map");

private volatile Map, Attribute> map;

@Override
public Attribute attr(AttributeKey key) {
Map, Attribute> map = this.map;
if (map == null) {
// Not using ConcurrentHashMap due to high memory consumption.
//创建一个初始值为2的IdentityHashMap,控制内存消耗
map = new IdentityHashMap, Attribute>(2);
if (!updater.compareAndSet(this, null, map)) {
//如果原子更新失败,即执行到这里时map被其它线程赋值,而不是预期的
//null值,那就直接使用当前值
map = this.map;
}
}

//同步块,如果获得的attribute是null,那就创建一个DefaultAttribute
synchronized (map) {
@SuppressWarnings("unchecked")
Attribute attr = (Attribute) map.get(key);
if (attr == null) {
attr = new DefaultAttribute(map, key);
map.put(key, attr);
}
return attr;
}
}
//......

可见作者在此处作了严密的控制,看到这里,心里充满了安全感 :D

另外要注意的是:
因为在 ChannelHandlerContext 中的 AttibuteMap 是绑定在该上下文中的,所以你在某个上下文中定义的 Attribute 在另一个handler的上下文中是看不到的。
Channel 中也实现了 AttributeMap,你可以使用绑定在 Channel 中的 AttributeMap,用来在handler之间传递attachment。
ctx.channel().attr(...)...;

你可能感兴趣的:(nio,netty,AttributeMap)