SpringMVC源码分析
作者:互联网
springMVC的核心:DispatchServlet; 请求转发器,前端控制器
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--DispatchServlet可以绑定spring的配置文件-->
<init-param>
<!-- 指定SpringMVC配置文件位置 -->
<param-name>contextConfigLocation</param-name>
<!--如果不指定 默认 /WEB-INF/上面的名字-servlet.xml-->
<param-value>classpath:spring-servlet.xml</param-value>
</init-param>
<!--启动级别1: 跟服务器一起启动-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--
所有请求都会被springmvc拦截
在springMVC中,/ 和 /*的区别
/ : 只匹配所有的请求,不会去匹配jsp页面
/* : 匹配所有的请求,也会匹配jsp页面
-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
DispatchServlet 是一个Servlet 继承关系图如下
doDispatch是SpringMVC的核心类DispatcherServlet中的核心方法,源码如下
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); // Determine handler for the current request.
// 根据当前的请求地址找到能处理这个请求的目标处理器类(控制类) 也就是我们写的Controller类,用@Controller注解标注的类。 mappedHandler = getHandler(processedRequest);
// 如果没有相应的处理器/控制器,则抛出一个异常或者404; if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // 拿到能执行这个类的所有方法的适配器;
// 根据当前处理器类获取到能执行这个处理器方法的适配器 如果使用的是注解@Controller,则就是AnnotationMethodHandlerAdapter适配器 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler. String method = request.getMethod(); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } } if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // Actually invoke the handler. 使用适配器执行目标方法 并返回一个ModelAndView对象。 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) { // As of 4.3, we're processing Errors thrown from handler methods as well, // making them available for @ExceptionHandler methods and other scenarios. dispatchException = new NestedServletException("Handler dispatch failed", err); }
// 转发到目标页面。并可以在请求域中获取数据 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Throwable err) { triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", err)); } finally { if (asyncManager.isConcurrentHandlingStarted()) { // Instead of postHandle and afterCompletion if (mappedHandler != null) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } else { // Clean up any resources used by a multipart request. if (multipartRequestParsed) { cleanupMultipart(processedRequest); } } } }
标签:分析,SpringMVC,mappedHandler,mv,request,源码,null,response,processedRequest 来源: https://www.cnblogs.com/lxy-java/p/12884455.html