MINA探究之IoFilterChain

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来实现想要的功能。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值