`
bachmozart
  • 浏览: 111368 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

cindy源码分析filterchain

    博客分类:
  • Java
阅读更多
常用的网络通讯框架主要有:Mina ,Grizzly,Cindy,Netty 等,看了下cindy的代码,和mina有很多相似的地方,实现的比mina精简很多,据说性能还要好于mina.参照代码实现了一下filterchain的HelloWorld版,简单说明一下cindy里对filterchain模式的应用.

首先定义filter接口,filter接口封装了session中的sessionStarted,sessionClosed,messageReceived等方法,为了简单,我只模拟一个send方法,用一个String的消息代替session对象

    public interface Filter {
	   void send(FilterChain chain, String msg);
    }


FilterChain是filter的一个管理容器,在cindy里filterChain管理2种filter,第一种是系统内部的filter,另外一种是用户定义的filter,看一下FilterChain的定义

public interface FilterChain {

	public void addFilter(Filter filter);

	public void send(String msg);
}

为了简单,我只定义了addFilter,而没有定义removeFilter方法,send方法其实是filterChain调用所管理的所有filter的一个方法,看一个具体实现

public abstract class AbstractFilterChain implements FilterChain {
	protected static final Filter NULL_FILTER = new NullFilter();
	protected static final Filter DISPACHER_FILTER = new FirstInnerFilter();

	protected abstract Filter nextFilter();

	public Filter next() {
		Filter filter = nextFilter();
		return filter != null ? filter : NULL_FILTER;
	}

	@Override
	public void send(String msg) {
		next().send(this, msg);
	}

}

在这个抽象类里,我们基本可以看出filterChain是如何管理所有filter的,首先filterChain里定义了2个系统内部的filter,FirstInnerFilter是filterChain里的第一个filter,在cindy里的名称是DispacherFilter,里面是通过一个线程池DefaultDispacher调用所有的filter的,NullFilter是系统的最后一个filter,当然我的实现是非常简单的,cindy实际上定义了很多个系统内部的filter,其中还有一个PacketDecoderFilter用于解码的filter,主要处理字节流转换成java对象,类似netty 里的MessageReconizer

每次调用send,方法,都会通过nextFilter取得下一个filter进行调用,看一下最终实现

public class DefaultFilterChain extends AbstractFilterChain {
	private Filter[] appFilters = new Filter[0];
	private Filter dispacherFilter = DISPACHER_FILTER;
	private int cursor = -1;

	@Override
	public void addFilter(Filter filter) {
		Filter[] newFilters = new Filter[appFilters.length + 1];
		if (appFilters.length > 0) {
			System.arraycopy(appFilters, 0, newFilters, 0, appFilters.length);
		}
		newFilters[appFilters.length] = filter;
		appFilters = newFilters;
	}

	@Override
	protected Filter nextFilter() {
		Filter filter = null;
		if (dispacherFilter != null) {
			filter = dispacherFilter;
			dispacherFilter = null;
		} else if (++cursor < appFilters.length) {
			filter = appFilters[cursor];
		} else {
			filter = NULL_FILTER;
		}
		return filter;
	}
}


addFilter比较好理解用于向chain容器内添加用户定义的filter
nextFilter是整个chain的调度中心,流程是:
首先调用系统内部的FirstInnerFilter,然后开始循环调用所有用户自定义的filter,最后是
系统内部的NullFilter,我们再看看各种filter的实现

   public class FirstInnerFilter implements Filter {

	@Override
	public void send(FilterChain chain, String msg) {
		System.out.println("first inner filter(Dispacher Filter): " + msg);
		chain.send(msg);
	}

}


FirstInnerFilter是容器里首个被调用的filter,在调用方法里,通过chain.send(msg),其实就是调用 FilterChain的 next().send(msg)方法,依此类推,遍历容器内所有的filter,下面是其他的实现:

public class NullFilter implements Filter {

	@Override
	public void send(FilterChain chain, String msg) {
		System.out.println("the final of the chain, NullFilter: " + msg);
	}

}


public class FilterAdapter implements Filter {

	@Override
	public void send(FilterChain chain, String msg) {
		chain.send(msg);
	}

}


所有的用户定义的filter继承自FilterAdapter,其实也可以不必这样的,可以直接在应用filter里调用chain.send(msg);

以下是两个用户自定义的filter示例

public class AppFilterA extends FilterAdapter {

	@Override
	public void send(FilterChain chain, String msg) {
		System.out.println("AppFilterA: " + msg);
		super.send(chain, msg);
	}

}


public class AppFilterB extends FilterAdapter {

	@Override
	public void send(FilterChain chain, String msg) {
		System.out.println("AppFilterB: " + msg);
		super.send(chain, msg);
	}

}


最后看一下测试代码:
public class TestChain {
	public void send(String msg) {
		DefaultFilterChain chain = new DefaultFilterChain();
		chain.addFilter(new AppFilterA());
		chain.addFilter(new AppFilterB());
		chain.send(msg);
	}

	public static void main(String[] args) {
		new TestChain().send("test msg");
	}
}


cindy里的DefaultFilterChain是定义在AbstractSession里的一个内部类.
程序输出:

first inner filter(Dispacher Filter): test msg
AppFilterA: test msg
AppFilterB: test msg
the final of the chain, NullFilter: test msg


以上是一个超简单的模拟cindy里filterChain的一个实现,源码结构大体是这样,当然功能要丰富得多,支持倒序和正序两种chain的执行顺序等.

源代码参照cindy3.0b1





3
0
分享到:
评论
2 楼 guoyu04 2010-11-22  
囧囧有神 写道
这种cursor的方式不利于对chain并发的访问,效率较低

这个怎么讲?
你是说数组么?
1 楼 囧囧有神 2010-09-01  
这种cursor的方式不利于对chain并发的访问,效率较低

相关推荐

    自定义FilterChain的编写

    在标准的`Filter`实现中,`FilterChain`由容器(如Tomcat)管理,但在自定义的`FilterChain`实现中,我们可以完全掌控这个过程,决定哪些过滤器先执行,哪些后执行。 让我们深入探讨如何自定义`FilterChain`: 1. ...

    mina学习资料与源码分析

    这个压缩包"mina学习资料与源码分析"包含了帮助你快速入门Mina、深入理解其工作原理和API的资源。下面,我们将深入探讨Mina的核心概念、功能以及如何利用它来开发网络应用。 Mina源于Java社区,其全称为“Minimal ...

    MINA源码分析,内涵类的讲解

    在这个“MINA源码分析,内涵类的讲解”中,我们将深入探讨MINA的核心组件和设计模式,以便更好地理解和利用这个强大的框架。 首先,我们需要了解MINA的基础架构。MINA的核心是`IoService`接口,它定义了服务端和...

    Servlet过滤器的简单使用源码+文档

    在标题"Servlet过滤器的简单使用源码+文档"中,我们可以理解为这个压缩包包含了一个关于Servlet过滤器的基础应用示例,以及相关的源代码和文档资料。描述中提到的"实现一个登陆界面",表明了过滤器可能被用作验证...

    Mina学习资料

    通过阅读Mina2源码分析.doc,你可以了解到实际项目中如何应用Mina框架,包括设置服务器、配置过滤器链、处理网络事件等。这份文档将提供具体案例,帮助你将理论知识转化为实践技能。 总结来说,Apache Mina是一个...

    Java mina2源码

    源码分析还能帮助我们理解Java的多线程、并发控制和事件驱动编程等高级特性,提升我们的编程技能和解决问题的能力。 此外,对于Java开发者来说,熟悉Mina2源码有助于理解其他类似的网络通信框架,比如Netty,因为...

    责任链模式 ChainFilter

    源码分析通常包括以下几个部分: 1. **过滤器接口或基类**:定义了处理请求的方法,如`doFilter()`,所有具体过滤器都要实现这个方法。 2. **具体过滤器类**:实现了过滤器接口或继承自基类,每个类代表一个具体的...

    购物车源码

    public void doFilter ServletRequest sRequest ServletResponse sResponse FilterChain chain throws IOException ServletException { HttpServletRequest request HttpServletRequest sRequest; String ...

    servlet源码

    `Filter`接口和`FilterChain`接口定义了过滤器的生命周期和执行流程,过滤器可以用来修改请求或响应,实现如认证、日志记录等功能。`@WebFilter`注解同样简化了过滤器的部署。 `ServletContext`接口是整个web应用...

    servlet 截获 html 静态页面源码

    `doFilter()`方法是Filter的核心,它接收三个参数:ServletRequest、ServletResponse和FilterChain。这个方法的逻辑是: 1. 强制转换`ServletRequest`和`ServletResponse`为`HttpServletRequest`和`...

    YII Framework的filter过滤器用法分析

    过滤器方法必须包含一个`$filterChain`参数,该参数是一个`CFilterChain`对象,用于控制过滤器链的执行。 ```php public function filterAccessControl($filterChain){ echo "---&gt;filterAccessControl"; $...

    Filter应用程序

    源码分析: Filter的定义在`javax.servlet.Filter`接口中,包含三个核心方法:`init(FilterConfig config)`用于初始化Filter,`doFilter(ServletRequest request, ServletResponse response, FilterChain chain)`是...

    mina2 源码 mina

    标题"mina2 源码 mina"暗示我们将探讨MINA2的源代码,这是一个非常有价值的资源,对于理解MINA的工作原理、学习如何构建网络应用程序以及定制MINA的行为非常有用。MINA的源码包含了丰富的注释和示例,可以帮助开发者...

    Mina2.0阅读源码笔记(很值得一看)

    #### 三、Mina 源码阅读笔记分析 1. **整体解读** - Mina 源码阅读通常采用自顶向下的方式,即先从整体结构入手,逐步深入细节。 - 阅读时应关注 Mina 的设计模式、架构原理及其核心组件之间的交互机制。 2. **...

    ant第三部分源码

    6. **任务链(ChainOfResponsibility)**:Ant的设计模式中,有些任务如`FilterChain`采用了责任链模式,使得多个过滤器可以串联起来处理输入内容。 7. **依赖管理**:Ant虽然没有像Maven那样强大的依赖管理功能,...

    Mina 框架源码解析-构建简单通信程序

    通过分析源码,我们可以看到Mina如何优雅地将网络编程的复杂性封装起来,让开发者可以更专注于应用的业务层面。同时,通过心跳机制,我们能够实时检测网络状况,确保服务的稳定性和可靠性。 总的来说,Mina框架提供...

    在Spring MVC或Spring Boot中使用Filter打印请求参数问题

    在Spring MVC和Spring Boot应用中,我们经常需要记录和跟踪HTTP请求与响应的详细信息,以便于调试和日志分析。通常,我们会使用AOP(面向切面编程)来实现这个功能,但有时我们也会选择在Filter中实现。Filter是...

    javax.servlet源码

    10. **FilterChain接口**:在过滤器链中,代表后续过滤器和最终的目标Servlet,调用`doFilter()`方法可以按顺序执行过滤器链。 11. **FilterConfig接口**:类似于ServletConfig,提供了过滤器的配置信息。 通过...

    Yii控制器中filter过滤器用法分析

    下面是关于Yii控制器中filter过滤器用法的详细知识点分析。 首先,Yii框架中的filter过滤器主要分为两大类:行为过滤器(Behavior Filter)和声明式过滤器(Declarative Filter)。行为过滤器以对象的形式存在,...

    JavaWeb开发几个常用的过滤器源码

    这里我们将深入探讨标题中提到的几个常用的过滤器及其源码实现。 首先,我们来看第一个过滤器:防止浏览器缓存页面的过滤器。这个过滤器的主要目的是确保每次用户访问页面时,都能获取到服务器最新更新的内容,而...

Global site tag (gtag.js) - Google Analytics