上文中,我们知道分发过程有以下步骤:
分发过程如下:
1. 判断是否设置了multipart resolver,设置的话转换为multipart request,没有的话则继续下面的步骤。
2. 根据当前request,获取hangdler。
3. 根据当前request,获取HandlerAdapter。
4. 如果支持http请求头,处理 last-modified header请求头。
5. 应用已注册interceptor的preHandle方法
6. HandlerAdapter处理请求。
7. 设置默认视图。
8. 应用已注册interceptor的postHandle方法。
9. 处理异常或者视图渲染。
这节,我们就详细看看步骤2 步骤3 如何根据request 获取handler 和handlerAdapter。
根据当前request获取handler,返回HandlerExecutionChain
/** * 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 { 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; }
先复习一下handlerMappings是如何获取到的:
// Find all HandlerMappings in the ApplicationContext, including ancestor contexts. Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false); if (!matchingBeans.isEmpty()) { this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values()); // We keep HandlerMappings in sorted order. OrderComparator.sort(this.handlerMappings); }
那么我们来看看如何获取到HandlerExecutionChain的:
/** * Look up a handler for the given request, falling back to the default * handler if no specific one is found. * @param request current HTTP request * @return the corresponding handler instance, or the default handler * @see #getHandlerInternal */ @Override public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { Object handler = getHandlerInternal(request); if (handler == null) { handler = getDefaultHandler(); } if (handler == null) { return null; } // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } return getHandlerExecutionChain(handler, request); }
Object handler = getHandlerInternal(request);在AbstractHandlerMapping.java中定义,具体实现有两个:
AbstractHandlerMethodMapping.java
/** * Look up a handler method for the given request. */ @Override protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); if (logger.isDebugEnabled()) { logger.debug("Looking up handler method for path " + lookupPath); } HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request); if (logger.isDebugEnabled()) { if (handlerMethod != null) { logger.debug("Returning handler method [" + handlerMethod + "]"); } else { logger.debug("Did not find handler method for [" + lookupPath + "]"); } } return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null); }
AbstractUrlHandlerMapping.java
/** * Look up a handler for the URL path of the given request. * @param request current HTTP request * @return the handler instance, or {@code null} if none found */ @Override protected Object getHandlerInternal(HttpServletRequest request) throws Exception { String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); Object handler = lookupHandler(lookupPath, request); if (handler == null) { // We need to care for the default handler directly, since we need to // expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well. Object rawHandler = null; if ("/".equals(lookupPath)) { rawHandler = getRootHandler(); } if (rawHandler == null) { rawHandler = getDefaultHandler(); } if (rawHandler != null) { // Bean name or resolved handler? if (rawHandler instanceof String) { String handlerName = (String) rawHandler; rawHandler = getApplicationContext().getBean(handlerName); } validateHandler(rawHandler, request); handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null); } } if (handler != null && logger.isDebugEnabled()) { logger.debug("Mapping [" + lookupPath + "] to " + handler); } else if (handler == null && logger.isTraceEnabled()) { logger.trace("No handler mapping found for [" + lookupPath + "]"); } return handler; }
给handler创建一个HandlerExecutionChain
/** * Build a {@link HandlerExecutionChain} for the given handler, including * applicable interceptors. * <p>The default implementation builds a standard {@link HandlerExecutionChain} * with the given handler, the handler mapping's common interceptors, and any * {@link MappedInterceptor}s matching to the current request URL. Subclasses * may override this in order to extend/rearrange the list of interceptors. * <p><b>NOTE:</b> The passed-in handler object may be a raw handler or a * pre-built {@link HandlerExecutionChain}. This method should handle those * two cases explicitly, either building a new {@link HandlerExecutionChain} * or extending the existing chain. * <p>For simply adding an interceptor in a custom subclass, consider calling * {@code super.getHandlerExecutionChain(handler, request)} and invoking * {@link HandlerExecutionChain#addInterceptor} on the returned chain object. * @param handler the resolved handler instance (never {@code null}) * @param request current HTTP request * @return the HandlerExecutionChain (never {@code null}) * @see #getAdaptedInterceptors() */ protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? (HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); chain.addInterceptors(getAdaptedInterceptors()); String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); for (MappedInterceptor mappedInterceptor : this.mappedInterceptors) { if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { chain.addInterceptor(mappedInterceptor.getInterceptor()); } } return chain; }