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

     */

    @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;

    }

 





 

你可能感兴趣的:(spring mvc)