定义:
使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
优点:
将请求者和处理者分开,两者解耦,提供系统灵活性。
角色:
1、抽象处理者(Handle):定义一个处理请求的接口。如果需要可以定义出一个方法以设定和返回
对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。
图中的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
2、具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择请求处理掉,或者将请求传给下家
。由具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
上图中的示意性的具体处理者ConcreteHandler类只有handleRequest()一个方法。
责任链模式的静态类结构如下图:
应用:
在 Spring MVC 的 HandlerExecutionChain 中
- HandlerExecutionChain 本身不会执行 interceptor 的逻辑,只是将请求分配给 chain 上注册的 interceptor 执行;
- HandlerExecutionChain 维护了 HandlerInterceptor 的集合
在 Spring MVC 的 DispatcherServlet 类中,有如下的主要代码逻辑:
doDispatch方法中,构建了 interceptor 执行链,将请求分配给 preHandle 执行,当 preHandle 方法返回为 false时,会调用到 afterCompletion 执行,最后调用 postHandle 方法。
源码如下:
protected void doDispatch (HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerExecutionChain mappedHandler = null;
mappedHandler = getHandler(processedRequest);
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
//当上面的 applyPreHandle 返回false时,继续向下执行到
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
//调用拦截器的 interceptor.preHandle
boolean applyPreHandle (HttpServletRequest request, HttpServletResponse response) {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(request, response, this.handler)) {
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;*}
}
return true;
}
void triggerAfterCompletion (HttpServletRequest request, HttpServletResponse response,Exception ex){
HandlerInterceptor interceptor = interceptors[i];
try {
interceptor.afterCompletion(request, response, this.handler, ex);
}
}
//调用拦截器的 interceptor.postHandle
void applyPostHandle (HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv){
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(request, response, this.handler, mv);
}
参考:
SpringMVC的执行流程
1、首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
2、DispatcherServlet——>HandlerMapping, HandlerMapping 将会把请求映射为HandlerExecutionChain 对象(包含一个Handler 处理器(页面控制器)对象、多个HandlerInterceptor 拦截器)对象,通过这种策略模式,很容易添加新的映射策略;
3、DispatcherServlet——>HandlerAdapter,HandlerAdapter 将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
4、HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter 将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView 对象(包含模型数据、逻辑视图名);
5、ModelAndView的逻辑视图名——> ViewResolver, ViewResolver 将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
6、View——>渲染,View会根据传进来的Model模型数据进行渲染(将数据添加到页面),此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
SpringMVC更多详情请查看