spring mvc DispatcherServlet详解之一---处理请求深入解析(续)
上文中,我們知道分發過程有以下步驟:
分發過程如下:
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*/@Overridepublic 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.*/@Overrideprotected 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*/@Overrideprotected 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;}?
?
轉載于:https://www.cnblogs.com/davidwang456/p/4100280.html
總結
以上是生活随笔為你收集整理的spring mvc DispatcherServlet详解之一---处理请求深入解析(续)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring mvc Dispatche
- 下一篇: 详解 Spring 3.0 基于 Ann