【应用】
以下是一段代码,Spring MVC 的 diapatcherServlet 的 doDispatch 方法中,获取与请求匹配的处理器(HandlerExecutionChain)
getHandler 方法的处理使用到了责任链模式,handlerMappings 是之前 Spring 容器初始化好的,通过遍历 handlerMappings 查找与 request 匹配的 Handler, 这里返回 HandlerExecutionChain 对象。这个 HandlerExecutionChain 对象到后面执行的时候再分析为什么返回的是这样一个对象。
【简介】
先来看一个图:这里表达是一个休假申请由于实际内容的不同,按照优先级别寻找可以审批该申请的角色的一个过程。
【百度百科】责任链模式是一种设计模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
责任链模式在面向对象程式设计里是一种软件设计模式,它包含了一些命令对象和一系列的处理对象。每一个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。该模式还描述了往该处理链的末尾添加新的处理对象的方法。
责任链模式实现了请求者和处理者的解耦。
责任链模式涉及到的角色如下所示:
● 抽象处理者 (Handler) 角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
● 具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
【Spring MVC 中的 Handler 实现】
接口 HandlerMapping 是上图 Handler 的代码实现,提供了 getHandler 方法用于判断 Hanlder 的具体实现类 ConcreteHanlder 是否可以处理该请求。如果可以处理,则返回一个 HandlerExecution 对象,里面包含一个请求处理器(a handler)和 任意个请求拦截器(any interceptors);如果不能处理,则返回 null 值。
那么,Spring MVC 如何将所有的 ConcreteHanlder 形成一条链,让某一个 ConcreteHanlder 在处理不了当前请求时可以获取下一个 ConcreteHanlder 呢 ?