常用的网络通讯框架主要有: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
分享到:
相关推荐
在标准的`Filter`实现中,`FilterChain`由容器(如Tomcat)管理,但在自定义的`FilterChain`实现中,我们可以完全掌控这个过程,决定哪些过滤器先执行,哪些后执行。 让我们深入探讨如何自定义`FilterChain`: 1. ...
这个压缩包"mina学习资料与源码分析"包含了帮助你快速入门Mina、深入理解其工作原理和API的资源。下面,我们将深入探讨Mina的核心概念、功能以及如何利用它来开发网络应用。 Mina源于Java社区,其全称为“Minimal ...
在这个“MINA源码分析,内涵类的讲解”中,我们将深入探讨MINA的核心组件和设计模式,以便更好地理解和利用这个强大的框架。 首先,我们需要了解MINA的基础架构。MINA的核心是`IoService`接口,它定义了服务端和...
在标题"Servlet过滤器的简单使用源码+文档"中,我们可以理解为这个压缩包包含了一个关于Servlet过滤器的基础应用示例,以及相关的源代码和文档资料。描述中提到的"实现一个登陆界面",表明了过滤器可能被用作验证...
通过阅读Mina2源码分析.doc,你可以了解到实际项目中如何应用Mina框架,包括设置服务器、配置过滤器链、处理网络事件等。这份文档将提供具体案例,帮助你将理论知识转化为实践技能。 总结来说,Apache Mina是一个...
源码分析还能帮助我们理解Java的多线程、并发控制和事件驱动编程等高级特性,提升我们的编程技能和解决问题的能力。 此外,对于Java开发者来说,熟悉Mina2源码有助于理解其他类似的网络通信框架,比如Netty,因为...
源码分析通常包括以下几个部分: 1. **过滤器接口或基类**:定义了处理请求的方法,如`doFilter()`,所有具体过滤器都要实现这个方法。 2. **具体过滤器类**:实现了过滤器接口或继承自基类,每个类代表一个具体的...
public void doFilter ServletRequest sRequest ServletResponse sResponse FilterChain chain throws IOException ServletException { HttpServletRequest request HttpServletRequest sRequest; String ...
`Filter`接口和`FilterChain`接口定义了过滤器的生命周期和执行流程,过滤器可以用来修改请求或响应,实现如认证、日志记录等功能。`@WebFilter`注解同样简化了过滤器的部署。 `ServletContext`接口是整个web应用...
`doFilter()`方法是Filter的核心,它接收三个参数:ServletRequest、ServletResponse和FilterChain。这个方法的逻辑是: 1. 强制转换`ServletRequest`和`ServletResponse`为`HttpServletRequest`和`...
过滤器方法必须包含一个`$filterChain`参数,该参数是一个`CFilterChain`对象,用于控制过滤器链的执行。 ```php public function filterAccessControl($filterChain){ echo "--->filterAccessControl"; $...
源码分析: Filter的定义在`javax.servlet.Filter`接口中,包含三个核心方法:`init(FilterConfig config)`用于初始化Filter,`doFilter(ServletRequest request, ServletResponse response, FilterChain chain)`是...
标题"mina2 源码 mina"暗示我们将探讨MINA2的源代码,这是一个非常有价值的资源,对于理解MINA的工作原理、学习如何构建网络应用程序以及定制MINA的行为非常有用。MINA的源码包含了丰富的注释和示例,可以帮助开发者...
#### 三、Mina 源码阅读笔记分析 1. **整体解读** - Mina 源码阅读通常采用自顶向下的方式,即先从整体结构入手,逐步深入细节。 - 阅读时应关注 Mina 的设计模式、架构原理及其核心组件之间的交互机制。 2. **...
6. **任务链(ChainOfResponsibility)**:Ant的设计模式中,有些任务如`FilterChain`采用了责任链模式,使得多个过滤器可以串联起来处理输入内容。 7. **依赖管理**:Ant虽然没有像Maven那样强大的依赖管理功能,...
通过分析源码,我们可以看到Mina如何优雅地将网络编程的复杂性封装起来,让开发者可以更专注于应用的业务层面。同时,通过心跳机制,我们能够实时检测网络状况,确保服务的稳定性和可靠性。 总的来说,Mina框架提供...
在Spring MVC和Spring Boot应用中,我们经常需要记录和跟踪HTTP请求与响应的详细信息,以便于调试和日志分析。通常,我们会使用AOP(面向切面编程)来实现这个功能,但有时我们也会选择在Filter中实现。Filter是...
10. **FilterChain接口**:在过滤器链中,代表后续过滤器和最终的目标Servlet,调用`doFilter()`方法可以按顺序执行过滤器链。 11. **FilterConfig接口**:类似于ServletConfig,提供了过滤器的配置信息。 通过...
下面是关于Yii控制器中filter过滤器用法的详细知识点分析。 首先,Yii框架中的filter过滤器主要分为两大类:行为过滤器(Behavior Filter)和声明式过滤器(Declarative Filter)。行为过滤器以对象的形式存在,...
这里我们将深入探讨标题中提到的几个常用的过滤器及其源码实现。 首先,我们来看第一个过滤器:防止浏览器缓存页面的过滤器。这个过滤器的主要目的是确保每次用户访问页面时,都能获取到服务器最新更新的内容,而...