IoFilterChain主要是维护一个这样的容器,这个容器维护一个IoSesion和相对应的IoFilterChain(1对1关系),都是串行执行的。
IOFilterChain中主要有事件触发的一些方法和保存每一个具体IoFilter的Entry(存放一些具体IoFilter相关的信息,主要包括名字,IoFilter,下一个IoFilter等,以及一些相对应的操作)。
IoFilterChain的一个实现类是:DefaultIoFilterChain。主要实现的功能是给IoFilterChain中增删IoFilter等。具体实现的办法可以用过如下源码来看:
public synchronized void addFirst(String name, IoFilter filter) {
checkAddable(name);
register(head, name, filter);
}
public synchronized void addLast(String name, IoFilter filter) {
checkAddable(name);
register(tail.prevEntry, name, filter);
}
public synchronized void addBefore(String baseName, String name,
IoFilter filter) {
EntryImpl baseEntry = checkOldName(baseName);
checkAddable(name);
register(baseEntry.prevEntry, name, filter);
}
public synchronized void addAfter(String baseName, String name,
IoFilter filter) {
EntryImpl baseEntry = checkOldName(baseName);
checkAddable(name);
register(baseEntry, name, filter);
}
public synchronized IoFilter remove(String name) {
EntryImpl entry = checkOldName(name);
deregister(entry);
return entry.getFilter();
}
public synchronized void remove(IoFilter filter) {
EntryImpl e = head.nextEntry;
while (e != tail) {
if (e.getFilter() == filter) {
deregister(e);
return;
}
e = e.nextEntry;
}
throw new IllegalArgumentException("Filter not found: "
+ filter.getClass().getName());
}
public synchronized IoFilter remove(Class<? extends IoFilter> filterType) {
EntryImpl e = head.nextEntry;
while (e != tail) {
if (filterType.isAssignableFrom(e.getFilter().getClass())) {
IoFilter oldFilter = e.getFilter();
deregister(e);
return oldFilter;
}
e = e.nextEntry;
}
throw new IllegalArgumentException("Filter not found: "
+ filterType.getName());
}
public synchronized IoFilter replace(String name, IoFilter newFilter) {
EntryImpl entry = checkOldName(name);
IoFilter oldFilter = entry.getFilter();
entry.setFilter(newFilter);
return oldFilter;
}
public synchronized void replace(IoFilter oldFilter, IoFilter newFilter) {
EntryImpl e = head.nextEntry;
while (e != tail) {
if (e.getFilter() == oldFilter) {
e.setFilter(newFilter);
return;
}
e = e.nextEntry;
}
throw new IllegalArgumentException("Filter not found: "
+ oldFilter.getClass().getName());
}
public synchronized IoFilter replace(
Class<? extends IoFilter> oldFilterType, IoFilter newFilter) {
EntryImpl e = head.nextEntry;
while (e != tail) {
if (oldFilterType.isAssignableFrom(e.getFilter().getClass())) {
IoFilter oldFilter = e.getFilter();
e.setFilter(newFilter);
return oldFilter;
}
e = e.nextEntry;
}
throw new IllegalArgumentException("Filter not found: "
+ oldFilterType.getName());
}
public synchronized void clear() throws Exception {
List<IoFilterChain.Entry> l = new ArrayList<IoFilterChain.Entry>(
name2entry.values());
for (IoFilterChain.Entry entry : l) {
try {
deregister((EntryImpl) entry);
} catch (Exception e) {
throw new IoFilterLifeCycleException("clear(): "
+ entry.getName() + " in " + getSession(), e);
}
}
}
private void register(EntryImpl prevEntry, String name, IoFilter filter) {
EntryImpl newEntry = new EntryImpl(prevEntry, prevEntry.nextEntry,
name, filter);
try {
filter.onPreAdd(this, name, newEntry.getNextFilter());
} catch (Exception e) {
throw new IoFilterLifeCycleException("onPreAdd(): " + name + ':'
+ filter + " in " + getSession(), e);
}
prevEntry.nextEntry.prevEntry = newEntry;
prevEntry.nextEntry = newEntry;
name2entry.put(name, newEntry);
try {
filter.onPostAdd(this, name, newEntry.getNextFilter());
} catch (Exception e) {
deregister0(newEntry);
throw new IoFilterLifeCycleException("onPostAdd(): " + name + ':'
+ filter + " in " + getSession(), e);
}
}
private void deregister(EntryImpl entry) {
IoFilter filter = entry.getFilter();
try {
filter.onPreRemove(this, entry.getName(), entry.getNextFilter());
} catch (Exception e) {
throw new IoFilterLifeCycleException("onPreRemove(): "
+ entry.getName() + ':' + filter + " in " + getSession(), e);
}
deregister0(entry);
try {
filter.onPostRemove(this, entry.getName(), entry.getNextFilter());
} catch (Exception e) {
throw new IoFilterLifeCycleException("onPostRemove(): " private class HeadFilter extends IoFilterAdapter {
@SuppressWarnings("unchecked")
@Override
public void filterWrite(NextFilter nextFilter, IoSession session,
WriteRequest writeRequest) throws Exception {
AbstractIoSession s = (AbstractIoSession) session;
// Maintain counters.
if (writeRequest.getMessage() instanceof IoBuffer) {
IoBuffer buffer = (IoBuffer) writeRequest.getMessage();
// I/O processor implementation will call buffer.reset()
// it after the write operation is finished, because
// the buffer will be specified with messageSent event.
buffer.mark();
int remaining = buffer.remaining();
if (remaining == 0) {
// Zero-sized buffer means the internal message
// delimiter.
s.increaseScheduledWriteMessages();
} else {
s.increaseScheduledWriteBytes(remaining);
}
} else {
s.increaseScheduledWriteMessages();
}
s.getWriteRequestQueue().offer(s, writeRequest);
if (!s.isWriteSuspended()) {
s.getProcessor().flush(s);
}
}
@SuppressWarnings("unchecked")
@Override
public void filterClose(NextFilter nextFilter, IoSession session)
throws Exception {
((AbstractIoSession) session).getProcessor().remove(((AbstractIoSession) session));
}
}
+ entry.getName() + ':' + filter + " in " + getSession(), e); } } private void deregister0(EntryImpl entry) { EntryImpl prevEntry = entry.prevEntry; EntryImpl nextEntry = entry.nextEntry; prevEntry.nextEntry = nextEntry; nextEntry.prevEntry = prevEntry; name2entry.remove(entry.name); }
通过调用这些方法,完成自己对自定制的IoFilterChain的配置。
DefaultIoFilterChain实现中默认在头和尾设置了两个Filter。先看head,源码如下:
private class HeadFilter extends IoFilterAdapter {
@SuppressWarnings("unchecked")
@Override
public void filterWrite(NextFilter nextFilter, IoSession session,
WriteRequest writeRequest) throws Exception {
AbstractIoSession s = (AbstractIoSession) session;
// Maintain counters.
if (writeRequest.getMessage() instanceof IoBuffer) {
IoBuffer buffer = (IoBuffer) writeRequest.getMessage();
// I/O processor implementation will call buffer.reset()
// it after the write operation is finished, because
// the buffer will be specified with messageSent event.
buffer.mark();
int remaining = buffer.remaining();
if (remaining == 0) {
// Zero-sized buffer means the internal message
// delimiter.
s.increaseScheduledWriteMessages();
} else {
s.increaseScheduledWriteBytes(remaining);
}
} else {
s.increaseScheduledWriteMessages();
}
s.getWriteRequestQueue().offer(s, writeRequest);
if (!s.isWriteSuspended()) {
s.getProcessor().flush(s);
}
}
@SuppressWarnings("unchecked")
@Override
public void filterClose(NextFilter nextFilter, IoSession session)
throws Exception {
((AbstractIoSession) session).getProcessor().remove(((AbstractIoSession) session));
}
}
Head主要的作用是做一个数据统计维持AbstractIoSession 中 scheduledWriteMessages这个统计量。然后将这个session放入 writeRequestQueue中等待写入。当这个IoFilter关闭时,则从IoProcessor中删除这个session以释放占用的相关资源。
tail相关源码如下:
private static class TailFilter extends IoFilterAdapter {
@Override
public void sessionCreated(NextFilter nextFilter, IoSession session)
throws Exception {
try {
session.getHandler().sessionCreated(session);
} finally {
// Notify the related future.
ConnectFuture future = (ConnectFuture) session
.removeAttribute(SESSION_CREATED_FUTURE);
if (future != null) {
future.setSession(session);
}
}
}
@Override
public void sessionOpened(NextFilter nextFilter, IoSession session)
throws Exception {
session.getHandler().sessionOpened(session);
}
@Override
public void sessionClosed(NextFilter nextFilter, IoSession session)
throws Exception {
AbstractIoSession s = (AbstractIoSession) session;
try {
s.getHandler().sessionClosed(session);
} finally {
try {
s.getWriteRequestQueue().dispose(session);
} finally {
try {
s.getAttributeMap().dispose(session);
} finally {
try {
// Remove all filters.
session.getFilterChain().clear();
} finally {
if (s.getConfig().isUseReadOperation()) {
s.offerClosedReadFuture();
}
}
}
}
}
}
@Override
public void sessionIdle(NextFilter nextFilter, IoSession session,
IdleStatus status) throws Exception {
session.getHandler().sessionIdle(session, status);
}
@Override
public void exceptionCaught(NextFilter nextFilter, IoSession session,
Throwable cause) throws Exception {
AbstractIoSession s = (AbstractIoSession) session;
try {
s.getHandler().exceptionCaught(s, cause);
} finally {
if (s.getConfig().isUseReadOperation()) {
s.offerFailedReadFuture(cause);
}
}
}
@Override
public void messageReceived(NextFilter nextFilter, IoSession session,
Object message) throws Exception {
AbstractIoSession s = (AbstractIoSession) session;
if (!(message instanceof IoBuffer)) {
s.increaseReadMessages(System.currentTimeMillis());
} else if (!((IoBuffer) message).hasRemaining()) {
s.increaseReadMessages(System.currentTimeMillis());
}
try {
session.getHandler().messageReceived(s, message);
} finally {
if (s.getConfig().isUseReadOperation()) {
s.offerReadFuture(message);
}
}
}
@Override
public void messageSent(NextFilter nextFilter, IoSession session,
WriteRequest writeRequest) throws Exception {
session.getHandler()
.messageSent(session, writeRequest.getMessage());
}
@Override
public void filterWrite(NextFilter nextFilter, IoSession session,
WriteRequest writeRequest) throws Exception {
nextFilter.filterWrite(session, writeRequest);
}
@Override
public void filterClose(NextFilter nextFilter, IoSession session)
throws Exception {
nextFilter.filterClose(session);
}
}
这个IoFilter主要是响应一些事件。具体通过方法名比较容易明白,这里不再罗嗦。
值得注意的是,所有的自定义的IoFilter插入都放在了head之后,tail之前。可以定义Logger,序列化工具,业务线程池等多个需要IoFilter。真正改进性能的地方可能就是业务处理的话,业务处理线程池,序列化的话,看能不能改进序列化的效率,如采用protocalBuffer这种东东了。具体的等谈Mina的Thread model的时候在展开一些池的使用场景吧。
关于IoFilter的使用可以直接参阅 http://mina.apache.org/iofilter.html 的内容来选择合适的filter来实现想要的功能。