美文网首页
Spring MVC 组件概述

Spring MVC 组件概述

作者: binge1024 | 来源:发表于2017-04-21 17:50 被阅读0次

    Spring MVC 的核心类DispatcherServlet入口为onRefresh()方法,而onRefresh()方法有直接调用了initStrategies()方法。代码如下:

    /**
         * Initialize the strategy objects that this servlet uses.
         * <p>May be overridden in subclasses in order to initialize further strategy objects.
         */
        protected void initStrategies(ApplicationContext context) {
            initMultipartResolver(context);
            initLocaleResolver(context);
            initThemeResolver(context);
            initHandlerMappings(context);
            initHandlerAdapters(context);
            initHandlerExceptionResolvers(context);
            initRequestToViewNameTranslator(context);
            initViewResolvers(context);
            initFlashMapManager(context);
        }
    

    HandlerMapping

    它的作用是根据请求(request)找到相应的Handler和Intercepters。HandlerMapping接口中只有一个getHandler()方法。对应的文档如下:

    /**
         * Return a handler and any interceptors for this request. The choice may be made
         * on request URL, session state, or any factor the implementing class chooses.
         * <p>The returned HandlerExecutionChain contains a handler Object, rather than
         * even a tag interface, so that handlers are not constrained in any way.
         * For example, a HandlerAdapter could be written to allow another framework's
         * handler objects to be used.
         * <p>Returns {@code null} if no match was found. This is not an error.
         * The DispatcherServlet will query all registered HandlerMapping beans to find
         * a match, and only decide there is an error if none can find a handler.
         * @param request current HTTP request
         * @return a HandlerExecutionChain instance containing handler object and
         * any interceptors, or {@code null} if no mapping found
         * @throws Exception if there is an internal error
         */
        HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
    

    我们也可以实现HandlerMapping接口,Override getHandler()方法自己定义一个MyHandlerMapping。

    public class MyHandlerMapping implements HandlerMapping{
         @Override
         public HandlerExecutionChain getHandler(HttpServletRequest request)throws Exception{
             String mothed = request.getMethod();
              if(mothed.equalsIgnoreCase("Get")){
                   return get方法对应的Handler;
              }else{
                   return 其他方法对应的Handler;
              } 
              return null;
         }
    }
    

    通过配置<bean>方式注册到spring容器中。

    HandlerAdapter

    HandlerMapping返回处理请求的Controller实例后,需要一个帮助定位具体请求方法的处理类,这个类就是HandlerAdapter,HandlerAdapter是处理器适配器,Spring MVC通过HandlerAdapter来实际调用处理方法。HandlerAdapter定义了如何处理请求的策略,通过请求url、请求Method和处理器的RequestMapping定义,最终确定使用处理类的哪个方法来处理请求,并检查处理类相应处理方法的参数以及相关的Annotation配置,确定如何转换需要的参数传入调用方法,并最终调用返回ModelAndView。HandlerAdapter接口的三个方法如下:

    /**
     * MVC framework SPI, allowing parameterization of the core MVC workflow.
     *
     * <p>Interface that must be implemented for each handler type to handle a request.
     * This interface is used to allow the {@link DispatcherServlet} to be indefinitely
     * extensible. The {@code DispatcherServlet} accesses all installed handlers through
     * this interface, meaning that it does not contain code specific to any handler type.
     *
     * <p>Note that a handler can be of type {@code Object}. This is to enable
     * handlers from other frameworks to be integrated with this framework without
     * custom coding, as well as to allow for annotation-driven handler objects that
     * do not obey any specific Java interface.
     *
     * <p>This interface is not intended for application developers. It is available
     * to handlers who want to develop their own web workflow.
     *
     * <p>Note: {@code HandlerAdapter} implementors may implement the {@link
     * org.springframework.core.Ordered} interface to be able to specify a sorting
     * order (and thus a priority) for getting applied by the {@code DispatcherServlet}.
     * Non-Ordered instances get treated as lowest priority.
     *
     * @author Rod Johnson
     * @author Juergen Hoeller
     * @see org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
     * @see org.springframework.web.servlet.handler.SimpleServletHandlerAdapter
     */
    public interface HandlerAdapter {
    
        /**
         * Given a handler instance, return whether or not this {@code HandlerAdapter}
         * can support it. Typical HandlerAdapters will base the decision on the handler
         * type. HandlerAdapters will usually only support one handler type each.
         * <p>A typical implementation:
         * <p>{@code
         * return (handler instanceof MyHandler);
         * }
         * @param handler handler object to check
         * @return whether or not this object can use the given handler
         */
        boolean supports(Object handler);
    
        /**
         * Use the given handler to handle this request.
         * The workflow that is required may vary widely.
         * @param request current HTTP request
         * @param response current HTTP response
         * @param handler handler to use. This object must have previously been passed
         * to the {@code supports} method of this interface, which must have
         * returned {@code true}.
         * @throws Exception in case of errors
         * @return ModelAndView object with the name of the view and the required
         * model data, or {@code null} if the request has been handled directly
         */
        ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
    
        /**
         * Same contract as for HttpServlet's {@code getLastModified} method.
         * Can simply return -1 if there's no support in the handler class.
         * @param request current HTTP request
         * @param handler handler to use
         * @return the lastModified value for the given handler
         * @see javax.servlet.http.HttpServlet#getLastModified
         * @see org.springframework.web.servlet.mvc.LastModified#getLastModified
         */
        long getLastModified(HttpServletRequest request, Object handler);
    
    }
    

    通过配置<bean>方式注册到spring容器中。

    HandlerExceptionResolver

    /**
     * Interface to be implemented by objects than can resolve exceptions thrown
     * during handler mapping or execution, in the typical case to error views.
     * Implementors are typically registered as beans in the application context.
     *
     * <p>Error views are analogous to the error page JSPs, but can be used with
     * any kind of exception including any checked exception, with potentially
     * fine-granular mappings for specific handlers.
     *
     * @author Juergen Hoeller
     * @since 22.11.2003
     */
    public interface HandlerExceptionResolver {
    
        /**
         * Try to resolve the given exception that got thrown during on handler execution,
         * returning a ModelAndView that represents a specific error page if appropriate.
         * <p>The returned ModelAndView may be {@linkplain ModelAndView#isEmpty() empty}
         * to indicate that the exception has been resolved successfully but that no view
         * should be rendered, for instance by setting a status code.
         * @param request current HTTP request
         * @param response current HTTP response
         * @param handler the executed handler, or {@code null} if none chosen at the
         * time of the exception (for example, if multipart resolution failed)
         * @param ex the exception that got thrown during handler execution
         * @return a corresponding ModelAndView to forward to,
         * or {@code null} for default processing
         */
        ModelAndView resolveException(
                 HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
    
    }
    

    ViewResolver

    ViewResolver负责将String类型的逻辑视图和Locale解析我View类型的视图。它主要有一个方法,如下:

    /**
         * Resolve the given view by name.
         * <p>Note: To allow for ViewResolver chaining, a ViewResolver should
         * return {@code null} if a view with the given name is not defined in it.
         * However, this is not required: Some ViewResolvers will always attempt
         * to build View objects with the given name, unable to return {@code null}
         * (rather throwing an exception when View creation failed).
         * @param viewName name of the view to resolve
         * @param locale Locale in which to resolve the view.
         * ViewResolvers that support internationalization should respect this.
         * @return the View object, or {@code null} if not found
         * (optional, to allow for ViewResolver chaining)
         * @throws Exception if the view cannot be resolved
         * (typically in case of problems creating an actual View object)
         */
        View resolveViewName(String viewName, Locale locale) throws Exception;
    

    RequestToViewNameTranslator

    ViewResolver是通过viewName 来查找View的,但有些Handler处理完后,并没有设置View或者viewName,这是就需要从request来获取View了,如何从request来获取view呢?那就是RequestToViewNameTranslator所做的事情了。此接口中只有一个方法,如下:

    /**
         * Translate the given {@link HttpServletRequest} into a view name.
         * @param request the incoming {@link HttpServletRequest} providing
         * the context from which a view name is to be resolved
         * @return the view name (or {@code null} if no default found)
         * @throws Exception if view name translation fails
         */
        String getViewName(HttpServletRequest request) throws Exception;
    

    LocaleResolver

    ViewResolver (视图解析器)在解析视图的时候需要两个参数viewName和Locale。viewName可以通过Handler处理后获得或者通过RequestToViewNameTranslator从request中获取。Local从哪儿来呢?LocaleResolver可以从request中获取Locale。LocaleResolver接口的方法,如下:

    /**
     * Interface for web-based locale resolution strategies that allows for
     * both locale resolution via the request and locale modification via
     * request and response.
     *
     * <p>This interface allows for implementations based on request, session,
     * cookies, etc. The default implementation is
     * {@link org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver},
     * simply using the request's locale provided by the respective HTTP header.
     *
     * <p>Use {@link org.springframework.web.servlet.support.RequestContext#getLocale()}
     * to retrieve the current locale in controllers or views, independent
     * of the actual resolution strategy.
     *
     * <p>Note: As of Spring 4.0, there is an extended strategy interface
     * called {@link LocaleContextResolver}, allowing for resolution of
     * a {@link org.springframework.context.i18n.LocaleContext} object,
     * potentially including associated time zone information. Spring's
     * provided resolver implementations implement the extended
     * {@link LocaleContextResolver} interface wherever appropriate.
     *
     */
    public interface LocaleResolver {
    
        /**
         * Resolve the current locale via the given request. Can return a default locale as
         * fallback in any case.
         * @param request the request to resolve the locale for
         * @return the current locale (never {@code null})
         */
        Locale resolveLocale(HttpServletRequest request);
    
        /**
         * Set the current locale to the given one.
         * @param request the request to be used for locale modification
         * @param response the response to be used for locale modification
         * @param locale the new locale, or {@code null} to clear the locale
         * @throws UnsupportedOperationException if the LocaleResolver implementation does not
         * support dynamic changing of the locale
         */
        void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale);
    
    }
    

    ThemeResolver

    /**
     * Interface for web-based theme resolution strategies that allows for
     * both theme resolution via the request and theme modification via
     * request and response.
     *
     * <p>This interface allows for implementations based on session,
     * cookies, etc. The default implementation is
     * {@link org.springframework.web.servlet.theme.FixedThemeResolver},
     * simply using a configured default theme.
     *
     * <p>Note that this resolver is only responsible for determining the
     * current theme name. The Theme instance for the resolved theme name
     * gets looked up by DispatcherServlet via the respective ThemeSource,
     * i.e. the current WebApplicationContext.
     *
     * <p>Use {@link org.springframework.web.servlet.support.RequestContext#getTheme()}
     * to retrieve the current theme in controllers or views, independent
     * of the actual resolution strategy.
     */
    public interface ThemeResolver {
    
        /**
         * Resolve the current theme name via the given request.
         * Should return a default theme as fallback in any case.
         * @param request request to be used for resolution
         * @return the current theme name
         */
        String resolveThemeName(HttpServletRequest request);
    
        /**
         * Set the current theme name to the given one.
         * @param request request to be used for theme name modification
         * @param response response to be used for theme name modification
         * @param themeName the new theme name
         * @throws UnsupportedOperationException if the ThemeResolver implementation
         * does not support dynamic changing of the theme
         */
        void setThemeName(HttpServletRequest request, HttpServletResponse response, String themeName);
    
    }
    

    FlashMapManager

    /**
     * A strategy interface for retrieving and saving FlashMap instances.
     * See {@link FlashMap} for a general overview of flash attributes.
     */
    public interface FlashMapManager {
    
        /**
         * Find a FlashMap saved by a previous request that matches to the current
         * request, remove it from underlying storage, and also remove other
         * expired FlashMap instances.
         * <p>This method is invoked in the beginning of every request in contrast
         * to {@link #saveOutputFlashMap}, which is invoked only when there are
         * flash attributes to be saved - i.e. before a redirect.
         * @param request the current request
         * @param response the current response
         * @return a FlashMap matching the current request or {@code null}
         */
        FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response);
    
        /**
         * Save the given FlashMap, in some underlying storage and set the start
         * of its expiration period.
         * <p><strong>NOTE:</strong> Invoke this method prior to a redirect in order
         * to allow saving the FlashMap in the HTTP session or in a response
         * cookie before the response is committed.
         * @param flashMap the FlashMap to save
         * @param request the current request
         * @param response the current response
         */
        void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response);
    
    }
    

    相关文章

      网友评论

          本文标题:Spring MVC 组件概述

          本文链接:https://www.haomeiwen.com/subject/xkzdzttx.html