Spring MVC(2) - DispatcherServlet running process
Look again at the class inheritance structure
Business processing flow of http request in Servlet
// Called by the servlet container to allow the servlet to respond to a request. // The interface service defined in javax.servlet.Servlet is called by the servlet container // The specific implementation is in the HttpServlet class public void service(ServletRequest req, ServletResponse res) { HttpServletRequest request; HttpServletResponse response; try { request = (HttpServletRequest) req; response = (HttpServletResponse) res; } catch (ClassCastException e) { throw new ServletException("non-HTTP request or response"); } service(request, response); } // This method of the HttpServlet class will transfer the request to methods such as doGet doPost doDelete protected void service(HttpServletRequest req, HttpServletResponse resp){ } // class FrameworkServlet protected final void doGet(HttpServletRequest request, HttpServletResponse response) { processRequest(request, response); } // class FrameworkServlet protected final void processRequest(HttpServletRequest request, HttpServletResponse response) { try { // The implementation of this method is in the subclass DispatcherServlet doService(request, response); } } // class DispatcherServlet protected void doService(HttpServletRequest request, HttpServletResponse response) { // core logic doDispatch(request, response); }
Let's talk about the core processing flow of DispatcherServlet
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) { // step1, check whether it is a file upload, if so, convert the request by the corresponding bean processedRequest = checkMultipart(request); // step2, according to the request, get the handler, during the initialization process, // Will save the url and the corresponding Controller and method mapping relationship // During the getHandler process, the beans registered with HandlerMapping during initialization will be traversed. // HandlerMapping will obtain the handler according to its own rules, that is, the Controller and the corresponding method // In fact, it is generally obtained by traversing the mapping table, and an error will be returned if it cannot be obtained. // This step will also encapsulate all interceptors into handlers mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // step3, get the HandlerAdapter that supports the handler in the second step, // Actually, select one that supports the current handler from the registered HandlerAdapter HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // For Get and Head requests, if the current HandlerAdapter supports it, process last-modified // step4, apply the preHandle method of all interceptors of the handler, and return if there is a false // Note that if there is an interceptor false, the afterCompletion method of all executed interceptors is guaranteed to be called // Note: The execution order of preHandle is opposite to that of postHandle afterCompletion if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // step5, handleradapter triggers handler method call, real url method processing mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // If the view is empty, set the default view applyDefaultViewName(processedRequest, mv); // step6, apply the interceptor's postHandle method, // Note: postHandle method can handle ModelAndView mappedHandler.applyPostHandle(processedRequest, response, mv); // step7, do the final rendering to ModelAndView processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException) { // Rendering work, the specific process is to use the ViewResolver registered when the Servlet is initialized, such as InternalResourceViewResolver // According to viewName, generate different view objects (usually AbstractUrlBasedView subclass InternalResourceView) // Among them, a different view class will be generated for "redirect:xx" and "forward:xx" in viewName // Then fill in the properties of the view class, such as suffix and prefix are added to the url and set to the properties of the view class // The specific processing of the View class is to finally set the attributes in the Model to the request, and find the corresponding RequestDispather according to the url // RequestDispather will associate the current request and response with the corresponding resource, that is, the Jsp file render(mv, request, response); // Make the afterCompletion call of the interceptor mappedHandler.triggerAfterCompletion(request, response, null); } // The outermost catch still guarantees the interceptor's afterCompletion call catch(Excepton e) { // Make the afterCompletion call of the interceptor mappedHandler.triggerAfterCompletion(request, response, null); } }