// Process last-modified header, if supported by the handler. Stringmethod= request.getMethod(); booleanisGet="GET".equals(method); if (isGet || "HEAD".equals(method)) { longlastModified= ha.getLastModified(request, mappedHandler.getHandler()); if (logger.isDebugEnabled()) { logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified); } if (newServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } }
if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; }
// Actually invoke the handler. 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 = newNestedServletException("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, newNestedServletException("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); } } } }
protectedvoidnoHandlerFound(HttpServletRequest request, HttpServletResponse response)throws Exception { if (pageNotFoundLogger.isWarnEnabled()) { pageNotFoundLogger.warn("No mapping found for HTTP request with URI [" + getRequestUri(request) + "] in DispatcherServlet with name '" + getServletName() + "'"); } if (this.throwExceptionIfNoHandlerFound) { //抛出异常 thrownewNoHandlerFoundException(request.getMethod(), getRequestUri(request), newServletServerHttpRequest(request).getHeaders()); } else { //返回HttpServletResponse.SC_NOT_FOUND,即404 response.sendError(HttpServletResponse.SC_NOT_FOUND); } }
获取处理器适配器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
protected HandlerAdapter getHandlerAdapter(Object handler)throws ServletException { //handlerAdapters 处理器适配器集合,存放所有的处理器适配器 for (HandlerAdapter ha : this.handlerAdapters) { if (logger.isTraceEnabled()) { logger.trace("Testing handler adapter [" + ha + "]"); } // 检查适配器是否支持给定的处理器 if (ha.supports(handler)) { return ha; } } // 找不到对应的适配器则抛出异常 thrownewServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }
value 是可选的,作用和 Ordered 接口中的排序值一样,value 越小,优先级越高,默认值是 Ordered.LOWEST_PRECEDENCE,最低优先级。
从 Spring 4.0 开始,Spring 中的很多组件都支持基于 Order 注解的排序,即使目标组件的排序值(目标类或 @Bean 方法)考虑的集合注入也是如此。虽然此类排序值可能会影响注入点的优先级,但请注意它们不会影响单例启动顺序,这是由依赖关系和 @DependsOn(影响运行时确定的依赖关系)声明确定的正交关注点。
从 Spring 4.1 开始,标准 Priority 注解可以用作排序方案中该注解的替代品。请注意, @Priority 当必须选择单个元素是,可能会有其他语义。具体参见 AnnotationAwareOrderComparator#getPriority。
/** * 返回指定类型的排序值 * <p>Takes care of {@link Order @Order} and {@code@javax.annotation.Priority}. * @param type 要处理的类型,即被注解的类 * @return 排序值,如果没有找到对应的类型,返回null * @see #getPriority(Class) */ publicstatic Integer getOrder(Class<?> type) { return getOrder(type, null); }
/** * 返回指定类型的排序值,如果没有指定的类型,则返回默认的排序值 * <p>Takes care of {@link Order @Order} and {@code@javax.annotation.Priority}. * @param type the type to handle * @return the priority value, or the specified default order if none can be found * @see #getPriority(Class) */ publicstatic Integer getOrder(Class<?> type, Integer defaultOrder) { //优先获取 Order 注解的值 Orderorder= AnnotationUtils.findAnnotation(type, Order.class); if (order != null) { return order.value(); } // 如果没有声明 Order 注解, 返回 Priority 注解的值 IntegerpriorityOrder= getPriority(type); if (priorityOrder != null) { return priorityOrder; } // 如果两个注解都为 null, 则返回传入的默认排序值 defaultOrder return defaultOrder; }
/** * 返回 {@code javax.annotation.Priority} 注解的值,如果类型上没有声明 Priority 注解,则返回 null * @param type the type to handle * @return the priority value if the annotation is declared, or {@code null} if none */ publicstatic Integer getPriority(Class<?> type) { if (priorityAnnotationType != null) { // 获取类上面的 Priority 注解类对象 Annotationpriority= AnnotationUtils.findAnnotation(type, priorityAnnotationType); if (priority != null) { // 获取注解类的 value 值 return (Integer) AnnotationUtils.getValue(priority); } } //如果 Priority 注解没有加载,则直接返回 null returnnull; }