Spring MVC 組件概述

Spring MVC 的核心類DispatcherServlet入口為onRefresh()方法复唤,而onRefresh()方法有直接調(diào)用了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

它的作用是根據(jù)請求(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;

我們也可以實現(xiàn)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來實際調(diào)用處理方法店枣。HandlerAdapter定義了如何處理請求的策略,通過請求url、請求Method和處理器的RequestMapping定義鸯两,最終確定使用處理類的哪個方法來處理請求闷旧,并檢查處理類相應處理方法的參數(shù)以及相關的Annotation配置,確定如何轉(zhuǎn)換需要的參數(shù)傳入調(diào)用方法钧唐,并最終調(diào)用返回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 (視圖解析器)在解析視圖的時候需要兩個參數(shù)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);

}
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市及刻,隨后出現(xiàn)的幾起案子镀裤,更是在濱河造成了極大的恐慌,老刑警劉巖缴饭,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暑劝,死亡現(xiàn)場離奇詭異,居然都是意外死亡颗搂,警方通過查閱死者的電腦和手機担猛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來丢氢,“玉大人傅联,你說我怎么就攤上這事【尾欤” “怎么了蒸走?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長稍浆。 經(jīng)常有香客問我载碌,道長猜嘱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任嫁艇,我火速辦了婚禮朗伶,結果婚禮上,老公的妹妹穿的比我還像新娘步咪。我一直安慰自己论皆,他們只是感情好,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布猾漫。 她就那樣靜靜地躺著点晴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪悯周。 梳的紋絲不亂的頭發(fā)上粒督,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機與錄音禽翼,去河邊找鬼屠橄。 笑死,一個胖子當著我的面吹牛闰挡,可吹牛的內(nèi)容都是我干的锐墙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼长酗,長吁一口氣:“原來是場噩夢啊……” “哼溪北!你這毒婦竟也來了?” 一聲冷哼從身側響起夺脾,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤之拨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后劳翰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體敦锌,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡馒疹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年佳簸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颖变。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡生均,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出腥刹,到底是詐尸還是另有隱情马胧,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布衔峰,位于F島的核電站佩脊,受9級特大地震影響蛙粘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜威彰,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一出牧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧歇盼,春花似錦舔痕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至邢笙,卻和暖如春啸如,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背氮惯。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工组底, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人筐骇。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓债鸡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親铛纬。 傳聞我的和親對象是個殘疾皇子厌均,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)告唆,斷路器棺弊,智...
    卡卡羅2017閱讀 134,652評論 18 139
  • DispatcherServlet初始化了9個組件 HandlerMapping 根據(jù)request找到相應的處理...
    HeartGo閱讀 962評論 0 1
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,806評論 6 342
  • 0 系列目錄# WEB請求處理 WEB請求處理一:瀏覽器請求發(fā)起處理 WEB請求處理二:Nginx請求反向代理 W...
    七寸知架構閱讀 4,308評論 3 55
  • tip:不求多,但求精擒悬!只推薦給你最適合的模她! 學習路徑:知道創(chuàng)宇技能表 一、Linux 我也覺得linux很煩懂牧,但...
    Jewel591閱讀 1,588評論 0 8