责任链模式的定义:
责任链模式为请求创建了一个接收者对象的链,在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
在SpringMVC中dispatcherServlet的HandlerExecutionChain也应用了这一设计模式的思路(可能并不是太典型,这个最后总结):
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 { ... // Determine handler for the current request. mappedHandler = getHandler(processedRequest);// Determine handler adapter for the current request. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); ... if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } applydefaultviewName(processedRequest, mv); mappedHandler.applyPostHandle(processedRequest, response, mv); } ... }
重点看标红的代码,在dodispatch方法中定义并获取了HandlerExecutionChain的对象,然后调用了applyPreHandle、applyPostHandle方法。
首先看下HandlerExecutionChain的作用:
public class HandlerExecutionChain { private final Object handler; @Nullable private handlerinterceptor[] interceptors; @Nullable private List<handlerinterceptor> interceptorList; private int interceptorIndex = -1; ...
HandlerExecutionChain持有http请求的处理器,即代码中的handler对象,以及拦截器的数组interceptors,既处理http请求的具体逻辑,又使用拦截器对http请求进行拦截,而此处对于拦截器的调用就应用了责任链模式的思路:
applyPreHandle方法:
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { 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; }
此处遍历拦截器的数组,调用拦截器的preHandle方法对请求进行处理,并且只有当本次preHandle处理返回true时,下一个拦截器才会进行执行preHandle方法;如果返回false,就执行triggerAfterCompletion并跳出循环。
总结:为什么开头说不是特别典型的责任链模式,因为此处的拦截器没有包含对另一拦截器的引用,而是通过数组的方式来达到类似的效果。
triggerAfterCompletion方法:
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) throws Exception { handlerinterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = this.interceptorIndex; i >= 0; i--) { handlerinterceptor interceptor = interceptors[i]; try { interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable ex2) { logger.error("handlerinterceptor.afterCompletion threw exception", ex2); } } } }
此处逻辑类似,只不过这里调用的是拦截器的afterCompletion方法。
applyPostHandle方法:
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception { handlerinterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = interceptors.length - 1; i >= 0; i--) { handlerinterceptor interceptor = interceptors[i]; interceptor.postHandle(request, response, this.handler, mv); } } }
此处逻辑类似,只不过这里调用的是拦截器的postHandle方法。
典型责任链模式:
https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。