public class ProtocolCodecFilter extends IoFilterAdapter {
/** A logger for this class */
private static final Logger LOGGER = LoggerFactory.getLogger(ProtocolCodecFilter.class);
private static final Class<?>[] EMPTY_PARAMS = new Class[0];
private static final IoBuffer EMPTY_BUFFER = IoBuffer.wrap(new byte[0]);
private final AttributeKey ENCODER = new AttributeKey(ProtocolCodecFilter.class, "encoder");
private final AttributeKey DECODER = new AttributeKey(ProtocolCodecFilter.class, "decoder");
private final AttributeKey DECODER_OUT = new AttributeKey(ProtocolCodecFilter.class, "decoderOut");
private final AttributeKey ENCODER_OUT = new AttributeKey(ProtocolCodecFilter.class, "encoderOut");
...
private ProtocolDecoderOutput getDecoderOut(IoSession session, NextFilter nextFilter) {
ProtocolDecoderOutput out = (ProtocolDecoderOutput) session.getAttribute(DECODER_OUT);
if (out == null) {
// Create a new instance, and stores it into the session
out = new ProtocolDecoderOutputImpl();
session.setAttribute(DECODER_OUT, out);
}
return out;
}
...
}
package org.apache.mina.core.session;
import java.io.Serializable;
/**
* Creates a Key from a class name and an attribute name. The resulting Key will
* be stored in the session Map.<br>
* For instance, we can create a 'processor' AttributeKey this way :
*
* <pre>
* private static final AttributeKey PROCESSOR = new AttributeKey(
* SimpleIoProcessorPool.class, "processor");
* </pre>
*
* This will create the <b>SimpleIoProcessorPool.processor@7DE45C99</b> key
* which will be stored in the session map.<br>
* Such an attributeKey is mainly useful for debug purposes.
*
* @author <a href="http://mina.apache.org">Apache MINA Project</a>
*/
public final class AttributeKey implements Serializable {
/** The serial version UID */
private static final long serialVersionUID = -583377473376683096L;
/** The attribute's name */
private final String name;
public AttributeKey(Class<?> source, String name) {
this.name = source.getName() + '.' + name + '@' + Integer.toHexString(this.hashCode());
}
@Override
public String toString() {
return name;
}
@Override
public int hashCode() {
int h = 17 * 37 + ((name == null) ? 0 : name.hashCode());
return h;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof AttributeKey)) {
return false;
}
AttributeKey other = (AttributeKey) obj;
return name.equals(other.name);
}
}
session.getAttrubute(...) 中存储<KEY, VALUE>对的其实是:
private static class DefaultIoSessionAttributeMap implements IoSessionAttributeMap {
private final ConcurrentHashMap<Object, Object> attributes = new ConcurrentHashMap<Object, Object>(4);
...
}
Open Declaration int java.lang.String.hashCode()
Returns a hash code for this string. The hash code for a String object is computed as
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
using int arithmetic, where s[i] is the ith character of the string, n is the length of the string, and ^ indicates exponentiation. (The hash value of the empty string is zero.)
public class MyProtocolCodecFilter extends IoFilterAdapter {
/** A logger for this class */
private static final Logger LOGGER = LoggerFactory.getLogger(MyProtocolCodecFilter.class);
private static final Class<?>[] EMPTY_PARAMS = new Class[0];
private static final IoBuffer EMPTY_BUFFER = IoBuffer.wrap(new byte[0]);
private final AttributeKey ENCODER = new AttributeKey(MyProtocolCodecFilter.class, "encoder");
private final AttributeKey DECODER = new AttributeKey(MyProtocolCodecFilter.class, "decoder");
private final AttributeKey DECODER_OUT = new AttributeKey(MyProtocolCodecFilter.class, "decoderOut");
private final AttributeKey ENCODER_OUT = new AttributeKey(MyProtocolCodecFilter.class, "encoderOut");
...
...
}
调用的时候,由原先的:
connector.getFilterChain().addLast("my-codec", new ProtocolCodecFilter(new OwspMessageFactory()));
改成:
connector.getFilterChain().addLast("my-codec", new MyProtocolCodecFilter(new OwspMessageFactory()));