轻量级,简单易学
高效 , 基于请求响应的MVC框架
与Spring兼容性好,无缝结合
约定优于配置
功能强大:RESTful、数据验证、格式化、本地化、主题等
简洁灵活
public class DispatcherServlet extends FrameworkServlet { /** * Process the actual dispatching to the handler. 实际调度过程的处理器。 * <p>The handler will be obtained by applying the servlet's HandlerMappings in order. 处理程序将得到应用的有序的servlet的处理映射器。 * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters 处理调度器通过查询servlet的HandlerAdapters安装获得。 * to find the first that supports the handler class. 找到第一个处理程序类。 * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers HTTP方法都是由这种方法处理。由HandlerAdapters或handlers程序 * themselves to decide which methods are acceptable. 自己来决定哪些方法是可以接受的 * @param request current HTTP request 请求当前的HTTP请求 * @param response current HTTP response 响应当前的HTTP响应 * @throws Exception in case of any kind of processing failure 抛出Exception应对任何处理失败 */ @SuppressWarnings("deprecation") protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false;//是否是文件上传功能 /**The central class for managing asynchronous request processing, mainly intended as an SPI and not typically used directly by application classes. 意思是主要用来管理异步请求的处理。什么时候要用到异步处理呢?就是业务逻辑复杂(或者其他原因),为了避免请求线程阻塞,需要委托给另一个线程的时候。*/ 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. 确定当前请求的处理程序 // 通过handlerMappings找到对应的HandlerExecutionChain处理链 // HandlerExecutionChain包含了拦截器handlerInterceptor和真正处理请求的handler mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request.确定当前请求处理程序适配器 // 通过Handler获取对应的适配器,主要是用来做很多预处理 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler.如果处理程序支持,则处理最后修改的头文件 // 得到当前的http方法 String method = request.getMethod(); boolean isGet = HttpMethod.GET.matches(method); if (isGet || HttpMethod.HEAD.matches(method)) {//处理http的head方法。这种方法应该很少用 long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } } // 调用HandlerExecutionChain的interceptor // Handler的预处理,还记得刚才返回的HandlerExecutionChain封装了Handler和一些拦截器,现在就是调用拦截器的时候。 if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // Actually invoke the handler.真正的调用处理程序 // HandlerAdpater让Handler处理request与response,获取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); } } } } }