springmvc的执行过程的源码分析
2017-10-02 10:11
411 查看
1.前端控制器接收请求,调用doDispatch方法。
/** * Process the actual dispatching to the handler. * <p>The handler will be obtained by applying the servlet's HandlerMappings in order. * The HandlerAdapter will be obtained by querying the servlet's installed 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 * themselves to decide which methods are acceptable. * @param request current HTTP request * @param response current HTTP response * @throws Exception in case of any kind of processing failure */ 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 { //先检查是不是Multipart类型的,比如上传等,如果是Multipart类型的,则转换为MultipartHttpServletRequest类型 processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); //获取当前请求的Handler mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } //获取当前请求的处理器适配器 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); String method = request.getMethod(); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (logger.isDebugEnabled()) { 4000 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; } //执行处理器 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } //处理成默认视图名,就是添加前缀和后缀等 applyDefaultViewName(processedRequest, 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); } } } }
2.执行doDispatch方法中的getHandler方法获得处理器链。
// Determine handler for the current request. mappedHandler = getHandler(processedRequest);
getHandler方法的代码:
/** * Return the HandlerExecutionChain for this request. * <p>Tries all handler mappings in order. * @param request current HTTP request * @return the HandlerExecutionChain, or {@code null} if no handler could be found */ protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { //循环所有已注册的HandlerMapping(处理器映射) 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; }
hm.getHandler(request)的代码为:
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { //根据请求获取处理器 Object handler = getHandlerInternal(request); if (handler == null) { //如果没有找到就使用默认的处理器 handler = getDefaultHandler(); } if (handler == null) { return null; } //如果处理器是String类型,则表明是它是一个bean名称 if (handler instanceof String) { String handlerName = (String) handler; //根据这bean名称获取bean handler = getApplicationContext().getBean(handlerName); } //把获取的处理器封装成处理器链 return getHandlerExecutionChain(handler, request); }
3.获取处理器适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
/** * Return the HandlerAdapter for this handler object. * @param handler the handler object to find an adapter for * @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error. */ 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"); }
4.使用处理器适配器执行处理器获得ModelAndView
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
不同的处理器适配器有不同的实现,例如RequestMappingHandlerAdapter:
首先进入AbstractHandlerMethodAdapter的handle方法
@Override public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return handleInternal(request, response, (HandlerMethod) handler); }
handleInternal在RequestMappingHandlerAdapter中:
@Override protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { checkRequest(request); if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) { applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); } else { prepareResponse(response); } // Execute invokeHandlerMethod in synchronized block if required. if (this.synchronizeOnSession) { HttpSession session = request.getSession(false); if (session != null) { Object mutex = WebUtils.getSessionMutex(session); synchronized (mutex) { return invokeHandlerMethod(request, response, handlerMethod); } } } return invokeHandlerMethod(request, response, handlerMethod); }
5.进行视图渲染,将model的数据填充到request
执行doDispatch方法中的processDispatchResult方法。
/** * Handle the result of handler selection and handler invocation, which is * either a ModelAndView or an Exception to be resolved to a ModelAndView. */ private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception { boolean errorView = false; if (exception != null) { if (exception instanceof ModelAndViewDefiningException) { logger.debug("ModelAndViewDefiningException encountered", exception); mv = ((ModelAndViewDefiningException) exception).getModelAndView(); } else { Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); mv = processHandlerException(request, response, handler, exception); errorView = (mv != null); } } // Did the handler return a view to render? if (mv != null && !mv.wasCleared()) { render(mv, request, response); if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } else { if (logger.isDebugEnabled()) { logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() + "': assuming HandlerAdapter completed request handling"); } } if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) { // Concurrent handling started during a forward return; } if (mappedHandler != null) { mappedHandler.triggerAfterCompletion(request, response, null); } }
在render方法中进行渲染。
/** * Render the given ModelAndView. * <p>This is the last stage in handling a request. It may involve resolving the view by name. * @param mv the ModelAndView to render * @param request current HTTP servlet request * @param response current HTTP servlet response * @throws ServletException if view is missing or cannot be resolved * @throws Exception if there's a problem rendering the view */ protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception { // Determine locale for request and apply it to the response. Locale locale = this.localeResolver.resolveLocale(request); response.setLocale(locale); View view; if (mv.isReference()) { // We need to resolve the view name. view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request); if (view == null) { throw new ServletException("Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" + getServletName() + "'"); } } else { // No need to lookup: the ModelAndView object contains the actual View object. view = mv.getView(); if (view == null) { throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " + "View object in servlet with name ' aff7 " + getServletName() + "'"); } } // Delegate to the View object for rendering. if (logger.isDebugEnabled()) { logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'"); } try { view.render(mv.getModelInternal(), request, response); } catch (Exception ex) { if (logger.isDebugEnabled()) { logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'", ex); } throw ex; } }
相关文章推荐
- SpringMVC拦截器执行过程源码分析
- Struts中ActionServlet源码深入分析执行过程
- springMVC源码分析--访问请求执行ServletInvocableHandlerMethod和InvocableHandlerMethod
- 源码分析之struts1自定义方法的使用与执行过程
- mybatis源码学习之执行过程分析(0)——配置文件加载(io包)
- zeppelin源码分析(6)——note的执行过程
- springMVC源码分析--访问请求执行ServletInvocableHandlerMethod和InvocableHandlerMethod
- JSP运行原理以及执行过程源码分析
- yii框架源码分析之Yii::createWebApplication()->run() 执行过程分析
- springMVC源码分析--访问请求执行ServletInvocableHandlerMethod和InvocableHandlerMethod
- Mybatis架构设计及源码分析-一条语句执行的过程
- 【spring源码学习】springMVC之映射,拦截器解析,请求数据注入解析,DispatcherServlet执行过程
- dubbo源码分析-client执行过程
- (Spring源码解析)一步一步分析,springMVC项目启动过程(二)
- springmvc源码分析——入门看springmvc的加载过程
- hive 执行过程源码分析
- mysql源码分析之SQL执行过程简介
- SpringMVC解析请求响应请求过程-源码分析
- springMVC源码分析--HandlerInterceptor拦截器调用过程(二)
- Android动画执行过程源码分析