什么是责任链模式:
责任链模式是一种设计模式。在责任链模式里,很多处理器对象由每一个处理器对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个处理器决定处理此请求。
发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
责任链模式实现了请求者和处理者的解耦。
责任链模式的两个角色:
责任链模式涉及到的角色如下所示:
● 抽象处理者角色 :
定义出一个处理请求的接口。接口定义一个方法,用来设定和返回对下一个处理器对象的引用。
● 具体处理者角色 :
具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。
SpringMVC中的责任链模式的体现:
在 SpringMVC 的 DispatcherServlet 类的doDispatch方法中,构建了 一个 处理器拦截器HandlerInterceptor的执行链。
1)HandlerExecutionChain介绍:
在该doDispatch方法中,使用到了HandlerExecutionChain这个类。
HandlerExecutionChain这个类维护了一个 HandlerInterceptor处理器拦截器 的集合,我们称之为拦截器执行链chain。
HandlerExecutionChain这个类 本身不会执行 处理器拦截器HandlerInterceptor 的逻辑,只是将请求分配给 拦截器执行链chain 里边的 处理器拦截器HandlerInterceptor;
2)拓展:分析doDispatch()方法:
分析doDispatch()方法,有以下几个步骤:
1,getHandler()方法:
1.1,调用getHandler()方法, 获取该请求的handler处理器,
该handler处理器对象实际上是HandlerExecutionChain,它维护着一个请求拦截器执行链,它整体负责该请求的整个处理过程。
1.2,getHandler()方法是如何获取该请求的handler处理器呢?
通过一个处理器映射器集合handlerMappings ,
看源代码:
/**
* 调用HandlerMapping处理器映射器,请求获取Handle处理器
*/
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//如果处理器映射器集合不为空
if (this.handlerMappings != null) {
//遍历处理器映射器集合:
for (HandlerMapping mapping : this.handlerMappings) {
//调用每个处理器映射器的getHandler()方法,尝试获取处理器对象
HandlerExecutionChain handler = mapping.getHandler(request);
//如果处理器对象不为空,说明该处理器映射器获取到了正确的处理器,将其返回
if (handler != null) {
return handler;
}
}
}
return null;
}
2,执行handler处理器的applyPreHandle()方法,
该方法是责任链执行预处理方法,实则是将请求交给 handler处理器 里边的 处理器拦截器链 里边 注册的 处理器拦截器 去执行请求;
3,调用getHandlerAdapter()方法
3.1,调用getHandlerAdapter()方法,返回一个HandlerAdapter对象,即处理器适配器;
3.2,调用HandlerAdapter对象的handle()方法,该方法是实际的执行我们写的业务逻辑的部分,也就是我们的xxxController里边加了@RequestMapping注解的那些方法。 该方法执行完成之后,会返回一个ModelAndView对象。
4,执行handler处理器的applyPostHandle()方法,
该方法是责任链执行后处理方法,实则还是将请求交给 handler处理器 里边的 处理器拦截器链 里边注册的 处理器拦截器 去执行请求;
5,最后执行责任链上注册的处理器拦截器HandlerInterceptor的AfterCompletion方法。
3)详情来看doDispatch()方法的源代码:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// 获取该请求的handler,每一个handler实为HandlerExecutionChain,它为一个处理链,负责处理整个请求
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
// 责任链执行预处理方法,实则是将请求交给注册的请求拦截器执行
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 实际的执行逻辑的部分,也就是你加了@RequestMapping注解的方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
// 责任链执行后处理方法,实则是将请求交给注册的请求拦截器执行
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
// 处理返回的结果,触发责任链上注册的拦截器的AfterCompletion方法,其中也用到了HandlerExecutionChain注册的handler来处理错误结果
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
// 触发责任链上注册的拦截器的AfterCompletion方法
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
总结:
以上分析可以看出,在doDispatch方法中,构建了 处理器拦截器HandlerInterceptor的执行链,
先将请求分配给applyPreHandle()方法 执行,
当 applyPreHandle()方法 返回为 false时,
会再接着调用applyPostHandle()方法,
最后调用afterCompletion()方法。