`
bachmozart
  • 浏览: 110091 次
  • 性别: 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的编写

    不使用Servlet Filter接口,自定义FilterChain处理多个Filter执行顺序问题

    购物车源码

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

    责任链模式 ChainFilter

    简单的责任链代码 博文链接:https://liucunzhi.iteye.com/blog/1636463

    JSE基础与设计模式

    * 当前类名:FilterChain.java * 项目名称:JavaStudy * 创建时间:2011-12-28 */ package org.java.com.design.filter; import java.util.ArrayList; import java.util.List; public class FilterChain ...

    JSE基础与设计模式实例

    * 当前类名:FilterChain.java * 项目名称:JavaStudy * 创建时间:2011-12-28 */ package org.java.com.design.filter; import java.util.ArrayList; import java.util.List; public class FilterChain ...

    Filter_Listener相信代码使用

    import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax....

    Servlet过滤器使用

    b、doFilter(ServletRequest,ServletResponse,FilterChain): 这个方法完成实际的过滤操作,当客户请求访问于过滤器关联的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain参数用于访问后续过滤器。 ...

    Apache CXF 快速上手教程.docx

    CXF 是以消息处理为中心的,熟悉 JSP/Servlet 的开发者可以将拦截器视为 CXF 架构中的“Filter”,拦截器链也与“FilterChain”类似。通过拦截器,开发者可以方便地在消息传递、 处理的整个过程中对 CXF 进行扩展。...

    Filter过滤器

    在 Servlet API 中定义了三个接口类来开供开发人员编写 Filter 程序:Filter, FilterChain, FilterConfig。 Filter 程序是一个实现了 Filter 接口的 Java 类,与 Servlet 程序相似,它由 Servlet 容器进行调用和...

    struts2-1.zip

    MVC模式(model view controller) 模型:封装应用程序的数据和业务逻辑(POJO...对于servlet来说,拦截资源不是其所擅长的filter中的filterchain,这个API是servlet所没有的 Struts2中最主要的一个就是过滤器filter

    聊天室程序下载

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (encoding != null) { request.setCharacterEncoding(encoding); ...

    郑州大学软件学院机试题-2011-2012_JSP程序设计

    2. FilterChain接口中仅定义一个方法:public void doFilter(ServletRequest req,ServletResponse res),该方法的作用是。() (1分) A.用于将请求/响应继续沿过滤器链向后传给下一个过滤器。如果调用该方法的过滤...

    jQuery解析json数据实例分析

    本文实例分析了jQuery解析json数据的方法。分享给大家供大家参考,具体如下: 先来看看我们的Json数据格式: [ {id:01,name:"小白",old:29,sex:"男"}, {id:02,name:"小蓝",old:29,sex:"男"}, {id:03,name:"小雅",...

    Sosoo 1.0网络爬虫程序.doc

    FilterChain filters=new FilterChain(); DocumentFilter filter=new LinkLocalizer(); filters.add(filter); robby.setFilters(filters); 6.启用机器人运行期监控。 当启动spider程序后,程序利用回调接口...

    跨域访问Filter实例

    JAVA配置跨越访问Filter APP要访问WEB系统,需要进行跨域设置 关键: public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {}

    登录过滤器

    FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; HttpSession session ...

    JAVA J2EE 类库文档

    FilterChain FilterConfig GenericServlet HttpServlet HttpServletRequest HttpServletRequestWrapper HttpServletResponse HttpServletResponseWrapper HttpSession HttpSessionActivationListener ...

    在线培训:Filter.rar

    培训主要学习以下几个知识点: 1.Filter简介 2.Filter基本工作原理 3.Filter的主要作用及Filter API 4.Filter接口 5.FilterChain接口 6.FilterConfig接口 7.Filter的部署 8.Filter的典型应用

    c3p0工具包(jdbc)

    import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax....

    servlet-api-2.4.jar.zip

    javax.servlet.FilterChain javax.servlet.http.Cookie javax.servlet.FilterConfig javax.servlet.ServletConfig javax.servlet.GenericServlet javax.servlet.ServletContext javax.servlet.ServletRequest javax....

Global site tag (gtag.js) - Google Analytics