责任链模式之Tomcat Filter应用

责任链模式是一种对象的行为型模式。

其定义为:很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象处理此请求。发出这个请求的客户端并不知道链上哪个对象最终会处理这个请求,这使得系统可以在不影响客户端的情况下动态的重新组织和分配责任。

结构:

  1. 抽象处理者(Handler) 角色:定义出一个处理请求的接口。

  2. 具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。【持有对下家的引用】

优点:

  1. 降低耦合,

  2. 简化对象,

  3. 增强对象职责灵活性,

  4. 方便新增处理类。

缺点:

  1. 不能保证请求被接收,

  2. 系统性能受影响,容易造成循环调用。

例:dubbo里调用链/过滤链 的创建就是 责任链模式,tomcat filter也使用了责任链模式。

分析Tomcat Filter

核心逻辑入口:org.apache.catalina.core.StandardWrapperValve#invoke。

StandardWrapperValve 是 StandardWrapper的基础阀,其作用是加载Servlet,创建Filter过滤器,最终会调用Servlet的service方法。

//StandardWrapperValve类@Override
public final void invoke(Request request, Response response)throws IOException, ServletException {省略代码......//分配一个Servlet实例来处理这个请求if (!unavailable) {servlet = wrapper.allocate();}//为此请求创建过滤器链ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);//为此请求调用过滤器链,也会调用Servlet的service()方法filterChain.doFilter(request.getRequest(), response.getResponse());......
}

分配Servlet实例

本文基于springboot 2.2.2.RELEASE 框架代码分析。

servlet = wrapper.allocate(); 此行代码是分配一个Servlet实例来处理请求。

由DispatcherServletAutoConfiguration自动配置类 向容器中注入 DispatcherServlet Bean。所有的请求由该类分发。

......
public class DispatcherServletAutoConfiguration {protected static class DispatcherServletConfiguration {......@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)public DispatcherServlet dispatcherServlet(HttpProperties httpProperties, WebMvcProperties webMvcProperties) {DispatcherServlet dispatcherServlet = new DispatcherServlet();dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest());dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest());dispatcherServlet.setThrowExceptionIfNoHandlerFound(webMvcProperties.isThrowExceptionIfNoHandlerFound());dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents());dispatcherServlet.setEnableLoggingRequestDetails(httpProperties.isLogRequestDetails());return dispatcherServlet;}
}

创建过滤器链

ServletWebServerApplicationContextSpringApplicationContext容器的一个子类。

selfInitialize 方法会调用 getServletContextInitializerBeans 来获取ServletContextInitializer 实例对象集合。包含所有的ServletContextInitializer Bean对象(还适用于Servlet、Filter、EventListener Bean)。

ServletContextInitializer接口源码注释:

用于以编程方式配置 Servlet 3.0+ ServletContext的接口。

接口(并且不实现 WebApplicationInitializer} 将不会被SpringServletContainerInitializer 检测到,因此不会由 Servlet 容器自动引导。

此接口设计方式类似于 ServletContainerInitializer, 但其由 Spring 管理其生命周期而不是Servlet 容器。

addAdaptableBeans()

实例化并注册了所有实现Servlet、Filter及EventListener接口的类。所以此处就会加载Filter过滤器类(包括我们自定义的实现)。

//ServletContextInitializerBeans类protected void addAdaptableBeans(ListableBeanFactory beanFactory) {MultipartConfigElement multipartConfig = getMultipartConfig(beanFactory);addAsRegistrationBean(beanFactory, Servlet.class, new ServletRegistrationBeanAdapter(multipartConfig));addAsRegistrationBean(beanFactory, Filter.class, new FilterRegistrationBeanAdapter());for (Class<?> listenerType : ServletListenerRegistrationBean.getSupportedTypes()) {addAsRegistrationBean(beanFactory, EventListener.class, (Class<EventListener>) listenerType,new ServletListenerRegistrationBeanAdapter());}}

调用过滤器链

执行过滤器链,从ApplicationFilterConfig[] 数组中取出过滤器链执行,直到所有过滤器执行完毕。

private void internalDoFilter(ServletRequest request,ServletResponse response)throws IOException, ServletException {if (pos < n) {ApplicationFilterConfig filterConfig = filters[pos++];Filter filter = filterConfig.getFilter();filter.doFilter(request, response, this);省略......}servlet.service(request, response);......
}

最后会调用org.springframework.web.servlet.DispatcherServlet#doService。

责任链模式之Tomcat Filter应用相关推荐

  1. 折腾Java设计模式之责任链模式

    责任链模式 顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这种类型的设计 ...

  2. [转]《JAVA与模式》之责任链模式

    http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html 在阎宏博士的<JAVA与模式>一书中开头是这样描述责 ...

  3. 《JAVA与模式》之责任链模式

    2019独角兽企业重金招聘Python工程师标准>>> 详细请访问原博客:http://www.cnblogs.com/java-my-life/archive/2012/05/28 ...

  4. java设计模式之责任链模式以及在java中作用

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

  5. 责任链模式(Chain of Responsibility) Java实现

    责任链模式 责任链模式(Chain of Responsibility)定义 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递 ...

  6. Java 责任链模式

    顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这种类型的设计模式属于行为 ...

  7. 行为型模式:责任链模式

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

  8. 【设计模式】责任链模式

    顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这种类型的设计模式属于行为 ...

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

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

最新文章

  1. 一文详解 RNN 及股票预测实战(Python)!
  2. Js中判断变量存不存在的问题
  3. 简单回声服务器的实现
  4. python 井字游戏
  5. 刚体运动中变换矩阵的逆
  6. class没有发布到tomcat_Java 类在 Tomcat 中是如何加载的?
  7. 电商前台模板中文html5_跨境电商平台上产品如何上传?虾皮新版批量上传工具使用指南分享...
  8. 做科研,到底应该看什么?
  9. LeetCode 77 组合
  10. flask程序打包部署_如何使用Flask构建Web应用程序并将其部署到云中
  11. 小米12 Ultra外观设计曝光:白色陶瓷机身 后置硕大相机模组
  12. 【Kafka】Flink 消费 kafka 部分 分区 一直不提交 offset
  13. 论文阅读:BASNet:Boundary-Aware Salient Object Detection
  14. Drupal 紧急修复已遭利用的严重 0day
  15. j3服务器维修教程,服务器维修基本技术手册.docx
  16. 世界排名在20多位的无名小站
  17. DDD 战术模型之聚合
  18. FirefoxOS横竖屏切换应用开发一般方法总结
  19. 高效办公之思维导图半小时从入门与精通(Xmind2020版)
  20. 电脑重装系统按哪个键进入u盘启动项

热门文章

  1. FreeBuds 5耳套这样更换也太简单了吧
  2. java 配置jmx 参数_tomcat jmx配置
  3. 记一次CSDN的资源加载失败的问题的解决方法
  4. 我的世界java版怎么分开物品_我的世界:不小心死了,如何让物品不消失?老玩家教你5个妙招!...
  5. mysql 与gemfire的同步_Gemfire简单配置并测试
  6. 如何给X86的安卓机刷机(联想乐檬K80M)(线刷)
  7. 成功使用Python批量制作学员毕业海报心愿卡
  8. iphone怎么迁移数据_为什么需要此软件将数据迁移到新iPhone [赞助发布]
  9. mysql sed_连接sed命令
  10. JAVA三目运算符空指针解决办法