mina中责任链模式的实现
一、mina的框架回顾
责任链模式在mina中有重要的作用,其中Filter机制就是基于责任链实现的。
二、mina中filter
2.1、mina中的filterchain包结构
- IoFilter接口:Filter层的每个filter都是对上图IoFilter接口的实现。
- IoFilterChainBuilder接口和DefaultIoFilterChainBuilder实现不再细讲,从字面意思就是IoFilterChain的建造者。
- IoFilterEvent是代表filter事件,IoFilterLifeCycleException是指filter中出现循环链表异常。
三、mina的filter中实现类
3.0、NextFilter接口
NextFilter接口看上去和IoFilter接口差不多,但NextFilter接口代表的是“下一个filter”,这里的下是抽象的,因为在mina的各种链中,处理顺序有的是从头到尾,有的是从尾到头,而这里的下就代表了熟悉中的下一个filter。
3.1、HeadFilter
HeadFilter类只对发送消息处理方法重载,HeadFilter是发送消息最后的处理节点。
3.1.1、方法列表

3.1.2、调用IoService(边界)
关键代码见下面,将待发送的数据(字节)写到缓冲队列里,或直接调用flush()写到系统缓冲区。
- WriteRequestQueue writeRequestQueue = s.getWriteRequestQueue();
- if (!s.isWriteSuspended()) {
- if (writeRequestQueue.size() == 0) {
- // We can write directly the message
- s.getProcessor().write(s, writeRequest);
- } else {
- s.getWriteRequestQueue().offer(s, writeRequest);
- s.getProcessor().flush(s);
- }
- } else {
- s.getWriteRequestQueue().offer(s, writeRequest);
- }
3.1.1、全部源码
- 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();
- }
- WriteRequestQueue writeRequestQueue = s.getWriteRequestQueue();
- if (!s.isWriteSuspended()) {
- if (writeRequestQueue.size() == 0) {
- // We can write directly the message
- s.getProcessor().write(s, writeRequest);
- } else {
- s.getWriteRequestQueue().offer(s, writeRequest);
- s.getProcessor().flush(s);
- }
- } else {
- s.getWriteRequestQueue().offer(s, writeRequest);
- }
- }
- @SuppressWarnings("unchecked")
- @Override
- public void filterClose(NextFilter nextFilter, IoSession session) throws Exception {
- ((AbstractIoSession) session).getProcessor().remove(session);
- }
- }
3.2、TailFilter
TailFilter类只对接受消息处理方法重载。
3.2.1、方法列表
3.2.2、调用IoHandler(边界)
先判断待处理数据类型,如果不满足条件则继续读取数据。否则,调用handler类来接收处理消息。
- 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);
- }
- }
- }
3.2.3、全部源码
- 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);
- }
- }
3.3、Entry接口
Entry接口是IoFilterChain接口的一个内部接口,Entry是对IoFilter和NextFilter的封装整合接口,它属于链表IoFilterChain中的元素。指向当前和下一个过滤器。其中IoFilterChain接口代表了过滤器的容器,它本身就是一个对象引用形成的链表结构,默认的实现DefaultIoFilterChain其实有对链表头(head)的引用,找到头后就可以顺着头向下找,一直找到尾(tail)。
Entry接口与IoFilterChain接口关系如下:
3.4、EntryImpl类
EntryImpl是Entry接口的实现类,类的成员中含两个接口,filter和nextFilter,他们所用的接口是不一样的,至于为什么不用同一个接口,我想可能是因为接口职责单一的原则吧。
从EntryImpl类的构造方法看到,EntryImpl中保持对上一个节点和下一个节点引用,双向链表结构,name即过滤层名称,filter即过滤层的具体实现,而nextFilter是在构造方法中的内部实现。
- private class EntryImpl implements Entry {
- private EntryImpl prevEntry;
- private EntryImpl nextEntry;
- private final String name;
- private IoFilter filter;
- private final NextFilter nextFilter;
3.4.2、IoFilter接口和NextFilter接口:
虽然有IoFilter和NextFilter两个接口,接口方法都差不多,但最后真正业务的执行者还是IoFilter的实现,
IoFilter:IoFilterAdapter做为它的默认实现,完成了适配器的功能,以后的类可以直接继承它而不用实现IoFilter接口,想实现哪个方法只需要覆盖IoFilterAdapter的类的方法即可。
NextFilter:只起到转发的作用,看EntryImpl中的匿名的NextFilter实现类中,基本每个方法都是调用callNextSessionIdle()来完成转发的。
3.4.3、全部源码
- private class EntryImpl implements Entry {
- private EntryImpl prevEntry;
- private EntryImpl nextEntry;
- private final String name;
- private IoFilter filter;
- private final NextFilter nextFilter;
- private EntryImpl(EntryImpl prevEntry, EntryImpl nextEntry, String name, IoFilter filter) {
- if (filter == null) {
- throw new IllegalArgumentException("filter");
- }
- if (name == null) {
- throw new IllegalArgumentException("name");
- }
- this.prevEntry = prevEntry;
- this.nextEntry = nextEntry;
- this.name = name;
- this.filter = filter;
- this.nextFilter = new NextFilter() {
- public void sessionCreated(IoSession session) {
- Entry nextEntry = EntryImpl.this.nextEntry;
- callNextSessionCreated(nextEntry, session);
- }
- public void sessionOpened(IoSession session) {
- Entry nextEntry = EntryImpl.this.nextEntry;
- callNextSessionOpened(nextEntry, session);
- }
- public void sessionClosed(IoSession session) {
- Entry nextEntry = EntryImpl.this.nextEntry;
- callNextSessionClosed(nextEntry, session);
- }
- public void sessionIdle(IoSession session, IdleStatus status) {
- Entry nextEntry = EntryImpl.this.nextEntry;
- callNextSessionIdle(nextEntry, session, status);
- }
- public void exceptionCaught(IoSession session, Throwable cause) {
- Entry nextEntry = EntryImpl.this.nextEntry;
- callNextExceptionCaught(nextEntry, session, cause);
- }
- public void messageReceived(IoSession session, Object message) {
- Entry nextEntry = EntryImpl.this.nextEntry;
- callNextMessageReceived(nextEntry, session, message);
- }
- public void messageSent(IoSession session, WriteRequest writeRequest) {
- Entry nextEntry = EntryImpl.this.nextEntry;
- callNextMessageSent(nextEntry, session, writeRequest);
- }
- public void filterWrite(IoSession session, WriteRequest writeRequest) {
- Entry nextEntry = EntryImpl.this.prevEntry;
- callPreviousFilterWrite(nextEntry, session, writeRequest);
- }
- public void filterClose(IoSession session) {
- Entry nextEntry = EntryImpl.this.prevEntry;
- callPreviousFilterClose(nextEntry, session);
- }
- public String toString() {
- return EntryImpl.this.nextEntry.name;
- }
- };
- }public void addAfter(String name, IoFilter filter) {
- DefaultIoFilterChain.this.addAfter(getName(), name, filter);
- }
- public void addBefore(String name, IoFilter filter) {
- DefaultIoFilterChain.this.addBefore(getName(), name, filter);
- }
- public void remove() {
- DefaultIoFilterChain.this.remove(getName());
- }
- public void replace(IoFilter newFilter) {
- DefaultIoFilterChain.this.replace(getName(), newFilter);
- }
- }
3.5、IoFilterEvent
- public class IoEvent implements Runnable {
- private final IoEventType type;
- private final IoSession session;
- private final Object parameter;
- public IoEvent(IoEventType type, IoSession session, Object parameter) {
- if (type == null) {
- throw new IllegalArgumentException("type");
- }
- if (session == null) {
- throw new IllegalArgumentException("session");
- }
- this.type = type;
- this.session = session;
- this.parameter = parameter;
- }
- public void run() {
- fire();
- }
- public void fire() {
- switch (getType()) {
- case MESSAGE_RECEIVED:
- getSession().getFilterChain().fireMessageReceived(getParameter());
- break;
- case MESSAGE_SENT:
- getSession().getFilterChain().fireMessageSent((WriteRequest) getParameter());
- break;
- case WRITE:
- getSession().getFilterChain().fireFilterWrite((WriteRequest) getParameter());
- break;
- case CLOSE:
- getSession().getFilterChain().fireFilterClose();
- break;
- case EXCEPTION_CAUGHT:
- getSession().getFilterChain().fireExceptionCaught((Throwable) getParameter());
- break;
- case SESSION_IDLE:
- getSession().getFilterChain().fireSessionIdle((IdleStatus) getParameter());
- break;
- case SESSION_OPENED:
- getSession().getFilterChain().fireSessionOpened();
- break;
- case SESSION_CREATED:
- getSession().getFilterChain().fireSessionCreated();
- break;
- case SESSION_CLOSED:
- getSession().getFilterChain().fireSessionClosed();
- break;
- default:
- throw new IllegalArgumentException("Unknown event type: " + getType());
- }
- }
- }
IoFilterEvent 实现类
- public class IoFilterEvent extends IoEvent {
- /** A logger for this class */
- static Logger LOGGER = LoggerFactory.getLogger(IoFilterEvent.class);
- /** A speedup for logs */
- static boolean DEBUG = LOGGER.isDebugEnabled();
- private final NextFilter nextFilter;
- public IoFilterEvent(NextFilter nextFilter, IoEventType type, IoSession session, Object parameter) {
- super(type, session, parameter);
- if (nextFilter == null) {
- throw new IllegalArgumentException("nextFilter must not be null");
- }
- this.nextFilter = nextFilter;
- }
- public NextFilter getNextFilter() {
- return nextFilter;
- }
- @Override
- public void fire() {
- IoSession session = getSession();
- NextFilter nextFilter = getNextFilter();
- IoEventType type = getType();
- if (DEBUG) {
- LOGGER.debug("Firing a {} event for session {}", type, session.getId());
- }
- switch (type) {
- case MESSAGE_RECEIVED:
- Object parameter = getParameter();
- nextFilter.messageReceived(session, parameter);
- break;
- case MESSAGE_SENT:
- WriteRequest writeRequest = (WriteRequest) getParameter();
- nextFilter.messageSent(session, writeRequest);
- break;
- case WRITE:
- writeRequest = (WriteRequest) getParameter();
- nextFilter.filterWrite(session, writeRequest);
- break;
- case CLOSE:
- nextFilter.filterClose(session);
- break;
- case EXCEPTION_CAUGHT:
- Throwable throwable = (Throwable) getParameter();
- nextFilter.exceptionCaught(session, throwable);
- break;
- case SESSION_IDLE:
- nextFilter.sessionIdle(session, (IdleStatus) getParameter());
- break;
- case SESSION_OPENED:
- nextFilter.sessionOpened(session);
- break;
- case SESSION_CREATED:
- nextFilter.sessionCreated(session);
- break;
- case SESSION_CLOSED:
- nextFilter.sessionClosed(session);
- break;
- default:
- throw new IllegalArgumentException("Unknown event type: " + type);
- }
- }
- }
3.6、IoFilterLifeCycleException
mina中有3处使用了它,

mina中责任链模式的实现的更多相关文章
- es6 class中责任链模式与AOP结合
责任链模式大家应该都清楚,比如JS中的冒泡,Java中的拦截器.过滤器,都运用到了责任链模式. 可以看我之前的文章介绍责任链的:https://www.cnblogs.com/wuguanglin/p ...
- Activiti工作流学习笔记(四)——工作流引擎中责任链模式的建立与应用原理
原创/朱季谦 本文需要一定责任链模式的基础,主要分成三部分讲解: 一.简单理解责任链模式概念 二.Activiti工作流里责任链模式的建立 三.Activiti工作流里责任链模式的应用 一.简单理解责 ...
- C#设计模式-责任链模式
在现实生活中,有很多请求并不是一个人说了就算的,例如面试时的工资,低于1万的薪水可能技术经理就可以决定了,但是1万~1万5的薪水可能技术经理就没这个权利批准,可能就需要请求技术总监的批准,所以在面试的 ...
- C#设计模式(21)——责任链模式
一.引言 在现实生活中,有很多请求并不是一个人说了就算的,例如面试时的工资,低于1万的薪水可能技术经理就可以决定了,但是1万~1万5的薪水可能技术经理就没这个权利批准,可能就需要请求技术总监的批准,所 ...
- 设计模式学习之责任链模式(Chain of Responsibility,行为型模式)(22)
参考:http://www.cnblogs.com/zhili/p/ChainOfResponsibity.html 一.引言 在现实生活中,有很多请求并不是一个人说了就算的,例如面试时的工资,低于1 ...
- Java设计模式13:责任链模式
前言 来菜鸟这个大家庭10个月了,总得来说比较融入了环境,同时在忙碌的工作中也深感技术积累不够,在优秀的人身边工作必须更加花时间去提升自己的技术能力.技术视野,所以开一个系列文章,标题就轻松一点叫做最 ...
- 责任链模式的使用-Netty ChannelPipeline和Mina IoFilterChain分析
本文来自网易云社区 作者:乔安然 1. Chain of Responsiblity 定义: 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链 ...
- [工作中的设计模式]责任链模式chain
一.模式解析 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知 ...
- java设计模式之责任链模式以及在java中作用
责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个 ...
随机推荐
- tomcat_下载
1. http://tomcat.apache.org/ 2. 3.
- MVVM4
原地址(内容更丰富):http://www.cnblogs.com/888h/category/269092.html MVVM架构的简单解析 图1 View.ViewModel.Model之间的 ...
- python面向对象编程学习
python面向对象编程 基本概念理解 面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作 ...
- mysql中的左连接右连接内连接
一. 初始化SQL语句 /*join 建表语句*/ drop database if exists test; create database test; use test; /* 左表t1*/ dr ...
- Educational Codeforces Round 23D
给n个数求每个子区间的价值,区间的价值是最大值-最小值 套路题= =,分别算最大值和最小值的贡献,用并查集维护,把相邻点连一条边,然后sort,求最大是按边价值(两个点的最大价值)小的排,求最小是按最 ...
- iOS自动化探索(二)WDA API的使用
前面我们已经安装好了WebdriverAgent, 现在可以用Facebook官方提供的API来进行一些操作 WDA API官方页面: https://github.com/facebook/WebD ...
- Prism开发人员指南5-WPF开发 文档翻译(纯汉语版)
2014四月 Prism以示例和文档的形式帮助你更简单的设计丰富灵活易维护的WPF程序.其中使用的设计模式体现了一些重要的设计原则,例如分离关注点和松耦合,Prism帮助你利用松耦合组件设 ...
- C3P0使用详解
定义: C3P0是一个开源的JDBC连接池,目前使用它的开源项目有Hibernate,Spring等. 数据库连接池的基本思想就是为数据库连接建立一个"缓冲池".预先在缓冲池中放入 ...
- UI- 不易记知识点汇总
1.static: 所有的全局变量都是静态变量,而局部变量只有定义时加上类型修饰符static,才为局部静态变量. 静态变量并不是说其就不能改变值,不能改变值的量叫常量. 其拥有的值是可变的 ,而且它 ...
- 通过TortoiseSVN checkout的文件前面没有“状态标识”
问题描述:安装完成VisualSVN Server.VisualSVn和TortoiseSVN后,然后通过SVN Server新建Repository(仓库),用Visual Studio新建一个So ...