Filter责任链的创建

org.apache.catalina.core.ApplicationFilterFactory#createFilterChain,  此方法是被org.apache.catalina.core.StandardWrapperValve#invoke调用的,  对每个request都会创建FilterChain

public static ApplicationFilterChain createFilterChain(ServletRequest request,
Wrapper wrapper, Servlet servlet) {
//传入参数必须有一个servlet,这个servlet是在链的末尾被调用的. 这个servlet的查找过程是根据request的URI从web.xml配置中匹配出来的
// If there is no servlet to execute, return null
if (servlet == null)
return null; // Create and initialize a filter chain object
ApplicationFilterChain filterChain = null;
if (request instanceof Request) {
//.....
} else {
// Request dispatcher in use
filterChain = new ApplicationFilterChain();
}
// 责任链上绑定一个servlet
filterChain.setServlet(servlet);
filterChain.setServletSupportsAsync(wrapper.isAsyncSupported()); // Acquire the filter mappings for this Context
StandardContext context = (StandardContext) wrapper.getParent();
FilterMap filterMaps[] = context.findFilterMaps(); // If there are no filter mappings, we are done
if ((filterMaps == null) || (filterMaps.length == 0))
return (filterChain); // ...
//根据web.xml中filter的配置查找是否和当前request匹配
// Add the relevant path-mapped filters to this filter chain
for (int i = 0; i < filterMaps.length; i++) {
if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
continue;
}
if (!matchFiltersURL(filterMaps[i], requestPath))
continue;
ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
context.findFilterConfig(filterMaps[i].getFilterName());
if (filterConfig == null) {
// FIXME - log configuration problem
continue;
}
// 和request URI匹配,则filter会加入到责任链中
filterChain.addFilter(filterConfig);
} /.....// Return the completed filter chain
return filterChain;
}

filterChain创建完成后就会调用doFilter启用这个链,  此方法也是被org.apache.catalina.core.StandardWrapperValve#invoke调用的

org.apache.catalina.core.ApplicationFilterChain#doFilter

 private void internalDoFilter(ServletRequest request,
ServletResponse response)
throws IOException, ServletException { // Call the next filter if there is one
if (pos < n) {
//调用下一个filter, 每调用一次 当前pos都会++
ApplicationFilterConfig filterConfig = filters[pos++];
try {
Filter filter = filterConfig.getFilter(); //...
filter.doFilter(request, response, this); } catch (IOException | ServletException | RuntimeException e) {
throw e;
} catch (Throwable e) {
// ...
}
return;
} // We fell off the end of the chain -- call the servlet instance
try {
if (request.isAsyncSupported() && !servletSupportsAsync) {
request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR,
Boolean.FALSE);
}
// ... 在链的末尾,调用具体servlet的doService
servlet.service(request, response);
//
} catch (IOException | ServletException | RuntimeException e) {
throw e;
} catch (Throwable e) {
//...
} finally {
//...
}
}

Filter责任链模式的更多相关文章

  1. 由浅入深讲解责任链模式,理解Tomcat的Filter过滤器

    本文将从简单的场景引入, 逐步优化, 最后给出具体的责任链设计模式实现. 场景引入 首先我们考虑这样一个场景: 论坛上用户要发帖子, 但是用户的想法是丰富多变的, 他们可能正常地发帖, 可能会在网页中 ...

  2. 设计模式学习笔记(十四)责任链模式实现以及在Filter中的应用

    责任链模式(Chain Of Responsibility Design Pattern),也叫做职责链,是将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求.当有请求发生时,可将请求沿着这条 ...

  3. 责任链模式/chain of responsibility/行为型模式

    职责链模式 chain of responsibility 意图 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处 ...

  4. [工作中的设计模式]责任链模式chain

    一.模式解析 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知 ...

  5. JAVA设计模式之责任链模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...

  6. Java设计模式系列之责任链模式

    责任链模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道 ...

  7. JavaScript责任链模式

    介绍 责任链模式(Chain of responsibility)是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理 ...

  8. 设计模式(一)Chain Of Responsibility责任链模式

    设计模式篇章,源于网课的学习,以及个人的整理 在我们接收用户提交的字符时,常常会使用到过滤,在学习责任链模式前,我们是这样做的 1.定义一个类 public class MsgProcesser { ...

  9. 设计模式《JAVA与模式》之责任链模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其 ...

随机推荐

  1. Windows版本Apache+php的Xhprof应用

    [知识] {Apache} Apache是世界使用排名第一的Web服务器软件.它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一. {PHP} ...

  2. PTA 估值一亿的AI核心代码

    题面 比赛时被模拟题打自闭了,本来以为是个比较麻烦的模拟,实际上只要会C++的regex不到40行就能把这个题过掉了(orz smz) regex是用来处理正则表达式,里面有个函数regex_repl ...

  3. HDOJ 1164 Eddy's research

    上一篇已经讲了,但是转载别人的很乱,这里自己根据blog里面写的思路,重新写过了一个程序 #include <iostream> #include <malloc.h> #in ...

  4. 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-008排序算法的复杂度(比较次数的上下限)

    一. 1. 2.

  5. 格式化字符串攻击原理及示例.RP

    格式化字符串攻击原理及示例 一.类printf函数簇实现原理 类printf函数的最大的特点就是,在函数定义的时候无法知道函数实参的数目和类型. 对于这种情况,可以使用省略号指定参数表. 带有省略号的 ...

  6. spring项目中监听器作用-ContextLoaderListener

    附加链接:http://blog.csdn.net/zjw10wei321/article/details/40145241 作用:在启动Web 容器时,自动装配Spring applicationC ...

  7. mono-3.0.2安装指南

     install-mono.sh.zip   mono-3.0.2安装指南.pdf   mod_mono.diff.zip mono-3.0.2安装指南 一见 2012/12/27 目录 1. 前言 ...

  8. matlab处理:批处理图像分块

    有一个图像分块的代码,可以直接将一幅图像分为5*5的小块,代码如下: %[FileName,PathName] = uigetfile('*.*','Select the image'); Im=im ...

  9. 解决低版本Eclipse安装Findbugs插件无法显示问题

    问题描述 Eclipse安装Findbugs,显示安装成功,但是重启Eclipse在[Window]-[show view]-[other]中没有显示 原因 Eclipse版本太低,新版的Findbu ...

  10. Java从入门到放弃——05.修饰符static,final,权限修饰符

    本文目标 static final: 权限修饰符:public,private,protected,缺省 1.static 静态修饰符,被static修饰的变量或者方法会被加载进静态区内存,不需要创建 ...