我們在討論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);
}