我们在讨论Netty的服务器启动程序的bind()方法源码时,看到有这样的一段代码:
final Map<AttributeKey<?>, Object> attrs = attrs0();
synchronized (attrs) {
for (Entry<AttributeKey<?>, Object> e: attrs.entrySet()) {
@SuppressWarnings("unchecked")
AttributeKey<Object> key = (AttributeKey<Object>) e.getKey();
channel.attr(key).set(e.getValue());
}
}
很显然,它与ChannelOption类似,获取ServerBootstrap中的attrs属性值,遍历并设置Channel的AttributeMap
类型的attr属性。
实际上AttributeKey与ChannelOption非常类似,都是根据给定的名称获取一个常量。
package io.netty.util;
/**
* An attribute which allows to store a value reference. It may be updated atomically and so is thread-safe.
* Attribute允许存储一个值的引用。它会被原子的更新,所以是线程安全的
* @param <T> the type of the value it holds.
*/
public interface Attribute<T> {
/**
* Returns the key of this attribute.
* 返回这个attribute的key,这个key的类型AttributeKey。
*/
AttributeKey<T> key();
/**
* Returns the current value, which may be {@code null}
* 返回当前的值,可能是个null,值的类型就是
*/
T get();
/**
* Sets the value
* 设置值
*/
void set(T value);
/**
* Atomically sets to the given value and returns the old value which may be {@code null} if non was set before.
* 原子地设置一个给定的值,然后返回旧的值,如果之前没有设置过,则返回null
*/
T getAndSet(T value);
/**
* Atomically sets to the given value if this {@link Attribute}'s value is {@code null}.
* If it was not possible to set the value as it contains a value it will just return the current value.
* 如果Attribute的值是null,则原子地设置为给定的值。
* 当Attribute包含了一个值的时候,是不可能再去设置这个值的,他会返回当前的值。
*/
T setIfAbsent(T value);
/**
* Removes this attribute from the {@link AttributeMap} and returns the old value. Subsequent {@link #get()}
* calls will return {@code null}.
* 从这个AttributeMap种删除这个attribute,然后返回旧的值,之后的调用的get方法将会返回null
* If you only want to return the old value and clear the {@link Attribute} while still keep it in the
* {@link AttributeMap} use {@link #getAndSet(Object)} with a value of {@code null}.
* 如果你只是想返回旧的值,并清理Attribute,同时在还AttributeMap依然保留,我们可以调用getAndSet(Object),并制定value的参数为null.
* <p>
* Be aware that even if you call this method another thread that has obtained a reference to this {@link Attribute}
* via {@link AttributeMap#attr(AttributeKey)} will still operate on the same instance. That said if now another
* thread or even the same thread later will call {@link AttributeMap#attr(AttributeKey)} again, a new
* {@link Attribute} instance is created and so is not the same as the previous one that was removed. Because of
* this special caution should be taken when you call {@link #remove()} or {@link #getAndRemove()}.
* 需要小心的是,即使你在另外一个拥有这个Attribute引用的线程中调用了这个方法,这个引用通过AttributeMap#attr(AttributeKey)方法得到的,这样也是操作在一个实例上的。、
* 也就是说如果当前的另一个线程或者是同一个线程的后面再次调用了AttributeMap#attr(AttributeKey),一个新的Attribute实例将会被创建,它跟之前被删除的那个不一样了。
* 因为这个特殊的原因,当你调用remove或者getAndRemove的时候需要小心。
* @deprecated please consider using {@link #getAndSet(Object)} (with value of {@code null}).
* 废弃的:请考虑使用getAndSet(Object),并传入null.
*
*
*/
@Deprecated
T getAndRemove();
/**
* Atomically sets the value to the given updated value if the current value == the expected value.
* If it the set was successful it returns {@code true} otherwise {@code false}.
*/
boolean compareAndSet(T oldValue, T newValue);
/**
* remove方法与getAndRemove一样会产生副作用,应该调用set(null)来代替使用。
*/
@Deprecated
void remove();
}
与之关联的AttributeMap
package io.netty.util;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import io.netty.util.AttributeMap;
/**
* Holds {@link Attribute}s which can be accessed via {@link AttributeKey}.
* 保存能够通过AttributeKey访问的Attribute
* Implementations must be Thread-safe.
* 实现必须是线程安全的
*/
public interface AttributeMap {
/**
* Get the {@link Attribute} for the given {@link AttributeKey}. This method will never return null, but may return
* an {@link Attribute} which does not have a value set yet.
* 通过给定的AttributeKey获取Attribute,这个方法不会返回null,但是可能会返回一个没有设置任何值的Attribute。
*/
<T> Attribute<T> attr(AttributeKey<T> key);
/**
* Returns {@code} true if and only if the given {@link Attribute} exists in this {@link AttributeMap}.
* 只有当给定的Attribute存在于AttributeMap中时,才会返回true
*/
<T> boolean hasAttr(AttributeKey<T> key);
}