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. springMVC 返回json乱码问题

    多次遇见过这个问题,springMVC下返回给前端的json字符串,中文总是乱码,每次都要去翻一下之前的代码来看解决办法,有必要做个笔记记一下这个问题了. 解决方法: 在方法注解中加入如下: @Req ...

  2. Redis应用(django)

    自定义使用redis 创建url 定义单例模式连接池 import redis # 连接池 POOL = redis.ConnectionPool(host='10.211.55.4', port=6 ...

  3. 在windows远程提交任务给Hadoop集群(Hadoop 2.6)

    我使用3台Centos虚拟机搭建了一个Hadoop2.6的集群.希望在windows7上面使用IDEA开发mapreduce程序,然后提交的远程的Hadoop集群上执行.经过不懈的google终于搞定 ...

  4. Netty中的Future

    先看下Future的整个继承体系,还有一个ChannelFuture不在里面:     在并发编程中,我们通常会用到一组非阻塞的模型:Promise,Future 和 Callback.其中的 Fut ...

  5. 实现斗地主纸牌游戏---洗牌 发牌 看底牌的具体功能------Map集合存储方法 遍历的应用

    该Demo只是斗地主的游戏的一部分,实现的斗地主的组合牌  洗牌  发牌 看牌的功能,主要应用Map集合进行练习 package cn.lijun import java.util.ArrayList ...

  6. win8使用every'thing无法显示搜索结果的解决方法

    关键词: win8,everything,无搜索结果 进入everything ,tools->option右下角有个 restore defaults 如果安全软件阻拦,点击  允许 就行了, ...

  7. c# 捕获非托管异常

    在.NET 4.0之后,CLR将会区别出一些异常(都是SEH异常),将这些异常标识为破坏性异常(Corrupted State Exception).针对这些异常,CLR的catch块不会捕捉这些异常 ...

  8. Winform 自定义程序安装向导(可用于数据库升级等)

    在安装包,数据库升级过程中,大部分使用的是install shield.它的功能非常强大,不过就是太臃肿了. 我们可能希望能够自定义,更加灵活一下. 界面如: 这是来自于codeproject上的一个 ...

  9. 分层最短路-2018南京网赛L

    大概题意: 题意:N个点,M条带权有向边,求将K条边权值变为0的情况下,从点1到点N的最短路. 拓展:可以改变K条边的权值为x 做法:把每个点拆成k个点,分别表示还能使用多少次机会,构造新图. 实际写 ...

  10. poj 1743 Musical Theme(最长重复子串 后缀数组)

    poj 1743 Musical Theme(最长重复子串 后缀数组) 有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复 ...