我们都知道,使用springmvc要在web.xml中配置servlet:org.springframework.web.servlet.DispatcherServlet。那我们就从这个servlet开始,看看他的继承体系。
集成体系:DispatcherServlet是继承自FrameworkServlet(抽象类),而FrameworkServlet继承自HttpServlet,这是他们的继承体系。
springmvc处理请求思路:我们学习servlet的时候,请求会调用HttpServlet的service方法,service方法中有doGet,doPost方法,我们只要重写这些方法,就可以请求到我们自己编写的servlet中的doGet或doPost方法中。那么从这里可以看出,继承自HttpServlet的service方法就是处理请求的入口。那么springmvc就是根据这个思路来将请求扭转到自己的框架中的。
springmvc具体处理:FrameworkServlet重写了HttpServlet的service方法,而DispatcherServlet又继承了FrameworkServlet,所以当用户请求时,会调用DispatcherServlet从父类继承下来的service方法,该方法在FrameworkServlet实现。具体源码:
/** * Override the parent class implementation in order to intercept PATCH * requests. */ @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String method = request.getMethod(); if (method.equalsIgnoreCase(RequestMethod.PATCH.name())) { processRequest(request, response); } else { super.service(request, response); } }
可以看出:如果请求的方法符合springmvc处理的,就自己处理,如果不符合,就交父类HttpServlet处理。那么我们来看看processRequest(request, response);是怎么处理的。其中有一个重要的代码(由于代码过长,没有复制):前面都是一些初始化参数。
try {
doService(request, response);
}
然后再来看看doService,该方法是在DispatcherServlet中实现的。里面有一句重要的代码:
try {
doDispatch(request, response);
}
庐山真面目开始慢慢出来了。那我们具体来看看doDispatch(request, response);究竟是怎么做的.
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);//判断是否是Multipart,处理文件上传 multipartRequestParsed = (processedRequest != request); // Determine handler for the current request. mappedHandler = getHandler(processedRequest, false);//得到处理器映射器 //如果不存在处理器映射器,则返回 if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. 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 (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; } // Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());//将真正的处理交给处理器处理mappedHandler.getHandler(),有不同的处理器适配器 if (asyncManager.isConcurrentHandlingStarted()) { return; } applyDefaultViewName(request, mv); mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Error err) { triggerAfterCompletionWithError(processedRequest, response, mappedHandler, 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); } } } }
下面这个图是从别的博客下载过来的。http://www.cnblogs.com/sunniest/p/4555801.html
这段代码很重要,所以全截了。
首先判断请求是否是Multipart,处理文件上传的。
springmvc中有两个重要的概念:处理器映射器和处理器适配器
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { for (HandlerMapping hm : this.handlerMappings) { if (logger.isTraceEnabled()) { logger.trace( "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'"); } HandlerExecutionChain handler = hm.getHandler(request); if (handler != null) { return handler; } } return null; }
DispatcherServlet维护了一个handlerMappings的list集合,存放处理器映射器的。可以通过配置文件配置,他也有默认配置。在DispatcherServlet下的
DispatcherServlet.properties设置了一些属性。
上面代码得到HandlerExecutionChain,通过HandlerExecutionChain得到HandlerAdapter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { for (HandlerAdapter ha : this.handlerAdapters) { if (logger.isTraceEnabled()) { logger.trace("Testing handler adapter [" + ha + "]"); } if (ha.supports(handler)) { return ha; } } throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }