去哪找人做網(wǎng)站seo技術(shù)網(wǎng)網(wǎng)
前言:
前面我們分析了 Spring MVC 的工作流程源碼,其核心是 DispatcherServlet#doDispatch 方法,我們前面分析了獲取 Handler 的方法 DispatcherServlet#getHandler 方法,本篇我們重點分析一下獲取當(dāng)前請求的適配器 HandlerAdapter 的實現(xiàn)原理,具體方法入口是 DispatcherServlet#getHandlerAdapter。
Spring MVC 知識傳送門:
詳解 Spring MVC(Spring MVC 簡介)
Spring MVC 初始化源碼分析
Spring MVC 工作流程源碼分析
Spring MVC 源碼分析之 DispatcherServlet#getHandler 方法
** DispatcherServlet#getHandlerAdapter方法源碼分析**
DispatcherServlet#getHandlerAdapter方法就是從 handlerAdapters 中查詢匹配當(dāng)前請求的 Handler,只要找到了就不在循環(huán)直接返回,我們我們重點關(guān)注adapter.supports(handler) 這行代碼,這里實際調(diào)用的是接口的抽象類 AbstractHandlerMapping 中的 getHandler 方法,下面接著分析。
//org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {this.handlerAdapters 為空判斷 DispatcherServlet 初始化時注冊的 handlerAdaptersif (this.handlerAdapters != null) {//迭代遍歷Iterator var2 = this.handlerAdapters.iterator();while(var2.hasNext()) {HandlerAdapter adapter = (HandlerAdapter)var2.next();//找到匹配當(dāng)前 handler的 adapterif (adapter.supports(handler)) {//找到就返回return adapter;}}}//如果最后都沒找到 拋出異常throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
AbstractHandlerMethodAdapter#supports 方法源碼分析
AbstractHandlerMethodAdapter#supports 沒有什么復(fù)雜的邏輯,只是判斷了 handler 是否是 HandlerMethod 類型,至于 AbstractHandlerMethodAdapter#supportsInternal 方法它默認(rèn)返回 fasle,也就是說只要 handler 是 HandlerMethod 類型,就算匹配成功。
//org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#supports
public final boolean supports(Object handler) {//handler 是否是 HandlerMethod 類型 // this.supportsInternal 抽象方法 由子類實現(xiàn) RequestMappingHandlerAdapter#supportsInternal 默認(rèn)返回 truereturn handler instanceof HandlerMethod && this.supportsInternal((HandlerMethod)handler);
}
//org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#supportsInternal
protected abstract boolean supportsInternal(HandlerMethod var1);//org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#supportsInternal
protected boolean supportsInternal(HandlerMethod handlerMethod) {return true;
}
HandlerExecutionChain#applyPreHandle 方法源碼分析
HandlerExecutionChain#applyPreHandle 方法的主要左右就是調(diào)用攔截器的 preHandle 方法,如果有某個攔截器的 preHandle 方法返回 false,就會逆向調(diào)用返回 true 的攔截器的 triggerAfterCompletion 方法。
//org.springframework.web.servlet.HandlerExecutionChain#applyPreHandle
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {//獲取所有攔截器數(shù)組HandlerInterceptor[] interceptors = this.getInterceptors();//為空判斷if (!ObjectUtils.isEmpty(interceptors)) {//循環(huán)調(diào)用 攔截器的 preHandle 方法//this.interceptorIndex 記錄當(dāng)前攔截器的位置for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {HandlerInterceptor interceptor = interceptors[i];//判斷攔截器的 preHandle 方法返回值if (!interceptor.preHandle(request, response, this.handler)) {//攔截器 preHandle 方法返回 false 則反向調(diào)用返回 true 的那些攔截器的 afterCompletion 方法this.triggerAfterCompletion(request, response, (Exception)null);//返回 falsereturn false;}}}return true;
}//org.springframework.web.servlet.HandlerExecutionChain#triggerAfterCompletion
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) throws Exception {//獲取所有攔截器HandlerInterceptor[] interceptors = this.getInterceptors();//為空判斷if (!ObjectUtils.isEmpty(interceptors)) {//反向遍歷 這里是的 interceptorIndex 上面記錄了的 --i 就是反向遍歷for(int i = this.interceptorIndex; i >= 0; --i) {HandlerInterceptor interceptor = interceptors[i];try {//調(diào)用攔截器的 afterCompletion 方法interceptor.afterCompletion(request, response, this.handler, ex);} catch (Throwable var8) {logger.error("HandlerInterceptor.afterCompletion threw exception", var8);}}}}
HandlerExecutionChain#applyPostHandle 方法源碼分析
攔截器的 preHandle 方法調(diào)用完成后,就會調(diào)用 handle 方法處理具體請求(后面分析),handle 方法調(diào)用完成后就會調(diào)用攔截器的 applyPreHandle 方法, HandlerExecutionChain#applyPreHandle 方法的主要左右就是逆向調(diào)用攔截器的 postHandle 方法。
//org.springframework.web.servlet.HandlerExecutionChain#applyPostHandle
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {//獲取所有攔截器HandlerInterceptor[] interceptors = this.getInterceptors();//為空判斷if (!ObjectUtils.isEmpty(interceptors)) {for(int i = interceptors.length - 1; i >= 0; --i) {//逆向調(diào)用攔截器的 postHandle 方法HandlerInterceptor interceptor = interceptors[i];interceptor.postHandle(request, response, this.handler, mv);}}}
本篇主要分析了 Spring MVC 工作流程中比較簡單的幾個關(guān)鍵點,HandlerAdapter 的適配過程、攔截器的前置后置處理等,這些在流程中比較簡單的環(huán)節(jié)就放在一起分析了,希望可以幫助到有需要的朋友。
歡迎提出建議及對錯誤的地方指出糾正。