spring mvc Displatch Servlet詳細解の一つ---処理要求の詳細解析(続)

15498 ワード

上記では、配信プロセスには以下のステップがあることを知っている.
配布の過程は以下の通りです.
1.multiiprt requestを設置しているかどうかを判断し、設置するとmultiipad requestに変換し、ない場合は次のステップを継続します.
2.現在のrequestによってハング・ドルを取得します.
3.現在のrequestによって、HandlerAdapterを取得します.
4.httpリクエストヘッドをサポートするなら、処理する. last-modified header要求ヘッド.
5.登録済みのintercepterのpreHandle方法を適用する
6. Handler Adapter処理要求.
7.標準表示を設定します.
8. 登録済みのinterceptorのpostHandle方法を適用します.
9.異常または表示レンダリングを処理します.
この節については、手順2のステップ3を詳しく見てみます.どのようにrequestからhanderとhanderAdapterを取得しますか?
現在のrequestによってhandler Execution Charinを取得します.
    /**

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

    }
まずハンドルMappingsを復習してみます.
            // 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);

            }
じゃ、どうやってHandlerExecution Charinを取得したかを見てみます.
    /**

     * 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);

    }
AbstractUrl HandlerMapping.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;

    }
handlerExecution Charinをhandleerに作成します. 
    /**

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

    }