责任链模式

Posted by kyle on July 7, 2018

责任链模式简介

回忆一下我们请假的流程。首先,我们要向我们的组长提出申请,组长同意后,会把申请转发给部门负责人,部门负责人审核后报备给HR,然后HR将请假申请归档。

对于这样一系列流程,不管申请到哪一级,都有共同的行为:处理上一级流转过来的请假申请。

如果纯粹用顺序逻辑来处理这样的需求,其后果必然是造成大量臃肿、高耦合的代码。

责任链模式则可以很好地用来处理这样场景的需求。它将每一级抽象成一个节点,如果要新增新的层级,只需配置好节点顺序,然后让数据在串起来的节点中流转。这样,既可以保证每一层级的逻辑清晰明了,也可以保证在新增层级时,不对旧逻辑产生干扰,从而减小了耦合度。

责任链模式在生产中的应用

Tomcat中的Container

Tomcat主要由两个核心组件组成:Connector与Container。

其中Connector主要干了这么些事:

一、接收外部(如浏览器)发来的TCP连接请求;

二、创建Request对象与Response对象进行数据交换;

三、创建线程进行请求调度;

四、将请求转发给Container,由Container处理请求。

Container主要包括四种(逐级继承):

Engine:代表整个Catalina servlet引擎

Host:代表一个虚拟主机

Context:代表 Servlet 的 Context,它具备了 Servlet 运行的基本环境

Wrapper:Servlet的实例

Tomcat中的FilterChain

在Java Web项目中,常常对web服务器管理的所有web资源:例如JSP,Servlet,静态图片文件或静态HTML文件进行拦截、过滤,用以实现URL级别的权限控制、过滤敏感词汇、压缩响应信息等一些高级功能。

Servlet中的Filter正是用来辅助实现这一功能的接口。在一个Web应用中,可以编写多个Filter,这些Filter组合起来称之为一个FilterChain。

Servlet通过在web.xml中配置<filter>注册过滤器,然后用<filter-mapping>标签将过滤器映射到具体的接口实现上。

详细示例可参考:http://www.runoob.com/servlet/servlet-writing-filters.html

Dubbo中的Filter

Dubbo的Service层都是一些通用的、无状态的服务。在使用Dubbo的过程中,有时我们需要对数据进行过滤(类似拦截器),又或者需要限制访问权限(例如使用白名单机制)。

Dubbo提供了Filter扩展,可以通过自定义Filter来实现这些功能。

Mybatis中的Plugin

Mybatis可以配置各种Plugin,无论是官方提供的还是自己定义的。Plugin和Filter类似,就是在执行Sql语句的时候附加一些操作。Mybatis的责任链是通过动态代理的方式实现的,它使用Plugin代理实际的Executor类。