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. C++指针作为函数的参数进行传递时注意的问题

    应注意问题: 当指针作为函数的参数进行传递的时候,本质上还是进行的"值传递",也就是复制了一个新的指向该地址的指针变量. 只有在被调函数中,对指针进行引用操作,才可以达到不需要返回 ...

  2. ROS Learning-021 learning_tf-05(编程) now() 和 Time(0) 的区别 (Python版)

    ROS Indigo learning_tf-05 now() 和 Time(0)的区别 (Python版) - waitForTransform() 函数 我使用的虚拟机软件:VMware Work ...

  3. Android之对话框Dialog

    首先是确认对话框 //确认对话框 private void showLog1() { AlertDialog.Builder dialog = new AlertDialog.Builder(this ...

  4. C语言中的static的作用?

    在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条. (1)第一个作用:隐藏. 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性.为理解这句话 ...

  5. Hibernate 处理查询 in 字句

    from : http://blog.csdn.net/wodestudy/article/details/38200421 在处理hibernate的实体查询,一般可以采用多种方式处理复杂的查询,比 ...

  6. Spring @ResponseBody 返回乱码 的优雅解决办法

    版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 返回的结果中,中文全部被问号(?)代替的解决办法: *-servlet.xml的部分配置如下: <bean id=&quo ...

  7. Struts2 引入

    引入:   说:如果一个路径想访问一个类,需求怎么做? 第一种方法,用servlet 第二种方法,用过滤器 第三种方法如下图:把路径和方法都存到map里面,用反射可以执行类下的方法     第三中方法 ...

  8. Cookie seesion 赋值

    后台赋值: Session["uid"] = userid;//后台 后台取值: Label1.Text = Session["userid"].ToStrin ...

  9. C# DLL(程序集)的生成和调用

    日期:2018年11月24日 环境:Window 10,VS2015 一.利用VS2015自带的工具生成DLL 步骤: 1.利用C#准备一个.cs文件: using System; public cl ...

  10. requireJS入门基础

    参考  require.js详解 1.引用requireJS的html文件 <!DOCTYPE html> <head> <title>requireJS</ ...