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中作用
责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个 ...
随机推荐
- RedHat 6.4企业版利用iso镜像做本地yum源
修改文章:http://linux.cn/article-1017-1.html 而RedHat的yum则需要注册付费才能使用,如果不这样则有两种解决方案 1. 利用iso镜像做本地yum源 2. 利 ...
- Image合并添加文字内容
场景:将一个头像.二维码.文字信息添加到一张背景图片中,将这些信息合成一张图片. 代码已经测试验证.代码中图片自己随意找几张测试即可. 代码: import com.sun.image.codec.j ...
- 使用SpringMVC的crud操作时,进行数据修改,但是修改成功后,页面无法显示lastName属性值(被修改的那条记录)
我这个错误的原因在于,把map的键写错了,它必须和类名第一个字母小写相同 @ModelAttribute public void getEmployee(@RequestParam(value=&qu ...
- debug.js中的length的错误
记得昨天报了一个错,debug.js文件中的length未定义.前台不定位代码,后天也不报错,而debug.js是框架封装的文件,不是自己写的,无从得知是哪里的问题,而项目也已经重新启动过,无法撤销. ...
- Selenium with Python 009 - WebDriver API
官方API文档:https://seleniumhq.github.io/selenium/docs/api/py/api.html 更多详情,最好的学习方式可以查阅官方API文档或直接阅读源码,本文 ...
- idea debug调试快捷键
F9 resume programe 恢复程序 Alt+F10 show execution point 显示执行断点 F8 Step Over ...
- Microsoft Edge Certified with EBS 12.1 and 12.2
I am very pleased to announce that Microsoft Edge is certified as a new browser for Oracle E-Busines ...
- opencv:创建滑动条
函数原型: ,); #include <opencv.hpp> using namespace cv; #define WINDOW_NAME "线性混合示例" // ...
- jquery实现全选、不选、反选的两种方法
在取复选框checkbox的属性checked属性值时,发现一个问题,就是当用attr取值时,真的为"checked",假的为"undefined";当用pro ...
- C#—序列化(Serialize)和反序列化(NonSerialize)
(转自:http://www.cnblogs.com/Abel-Zhang/p/Serialize.html) 一.概述 序列化是把对象转变成流.相反的过程就是反序列化. 哪些场合用到这项技术呢? 1 ...