0x5 Spring系列:用SpringMVC工作原理詳解

      網(wǎng)友投稿 888 2025-03-31

      先來看一下什么是MVC模式

      MVC是一種設(shè)計(jì)模式。

      MVC的原理圖如下:

      springMVC簡(jiǎn)單介紹

      springMVC框架是以請(qǐng)求為驅(qū)動(dòng),圍繞Servlet設(shè)計(jì),將請(qǐng)求發(fā)給控制器,然后通過模型對(duì)象,分派器來展示請(qǐng)求結(jié)果視圖。其中核心類是DispatcherServlet,它是一個(gè)Servlet,頂層是實(shí)現(xiàn)的Servlet接口。

      SpringMVC使用

      需要在web.xml中配置DispatcherServlet。并且需要配置Spring-ContextLoaderListener

      org.springframework.web.context.ContextLoaderListener

      springmvc

      org.springframework.web.servlet.DispatcherServlet

      contextConfigLocation

      classpath:spring/springmvc-servlet.xml

      1

      0x5 Spring系列:用SpringMVC工作原理詳解

      springmvc

      /

      SpringMVC工作原理(重要)

      簡(jiǎn)單來說:

      客戶端發(fā)送請(qǐng)求 - >前端控制器DispatcherServlet接受客戶端請(qǐng)求 - >找到處理器映射HandlerMapping解析請(qǐng)求對(duì)應(yīng)的Handler-> HandlerAdapter會(huì)根據(jù)Handler來調(diào)用真正的處理器開處理請(qǐng)求,并處理相應(yīng)的業(yè)務(wù)邏輯 - >處理器返回一個(gè)模型視圖ModelAndView - >視圖解析器進(jìn)行解析 - >返回一個(gè)視圖對(duì)象 - >前端控制器DispatcherServlet渲染數(shù)據(jù)(Moder) - >將得到視圖對(duì)象返回給用戶

      如下圖所示:

      上圖的一個(gè)筆誤的小問題:Spring MVC的入口函數(shù)也就是前端控制器DispatcherServlet的作用是接收請(qǐng)求,響應(yīng)結(jié)果。

      流程說明(重要):

      (1)客戶端(瀏覽器)發(fā)送請(qǐng)求,直接請(qǐng)求到DispatcherServlet。

      (2)DispatcherServlet根據(jù)請(qǐng)求信息調(diào)用HandlerMapping,解析請(qǐng)求對(duì)應(yīng)的Handler。

      (3)解析到對(duì)應(yīng)的Handler(也就是我們平常說的Controller Control制器)后,開始由HandlerAdapter適配器處理。

      (4)HandlerAdapter會(huì)根據(jù)Handler來調(diào)用真正的處理器開處理請(qǐng)求,并處理相應(yīng)的業(yè)務(wù)邏輯。

      (5)處理器處理完業(yè)務(wù)后,會(huì)返回一個(gè)ModelAndView對(duì)象,Model是返回的數(shù)據(jù)對(duì)象,View是個(gè)邏輯上的View。

      (6)ViewResolver會(huì)根據(jù)邏輯查看查找實(shí)際的查看。

      (7)DispaterServlet把返回的模型傳給View(視圖渲染)。

      (8)把View返回給請(qǐng)求者(瀏覽器)

      SpringMVC重要組件說明

      如圖1所示,前端控制器的DispatcherServlet(不需要工程師開發(fā)),由框架提供(重要)

      作用:Spring MVC的入口函數(shù)。接收請(qǐng)求,響應(yīng)結(jié)果,相當(dāng)于轉(zhuǎn)發(fā)器,中央處理器。有了DispatcherServlet減少了其它組件之間的耦合度。用戶請(qǐng)求到達(dá)前端控制器,它就相當(dāng)于mvc模式中的C,DispatcherServlet的是整個(gè)流程控制的中心,由它調(diào)用其它組件處理用戶的請(qǐng)求;分發(fā)器的存在降低了組件之間的耦合性。

      2,處理器映射器的HandlerMapping(不需要工程師開發(fā)),由框架提供

      作用:根據(jù)請(qǐng)求的URL查找Handler.HandlerMapping負(fù)責(zé)根據(jù)用戶請(qǐng)求找到處理程序即處理器(控制器),用SpringMVC提供了不同的映射器實(shí)現(xiàn)不同的映射方式,例如:配置文件方式,實(shí)現(xiàn)接口方式,注解方式等。

      3,處理器適配器的HandlerAdapter

      作用:按照特定規(guī)則(的HandlerAdapter要求的規(guī)則)去執(zhí)行處理程序

      通過的HandlerAdapter對(duì)處理器進(jìn)行執(zhí)行,這是適配器模式的應(yīng)用,通過擴(kuò)展適配器可以對(duì)更多類型的處理器進(jìn)行執(zhí)行。

      如圖4所示,處理器處理程序(需要工程師開發(fā))

      注意:編寫Handler時(shí)按照HandlerAdapter的要求去做,這樣適配器才可以去正確執(zhí)行Handler

      Handler是繼DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler對(duì)具體的用戶請(qǐng)求進(jìn)行處理。

      由于Handler涉及到具體的用戶業(yè)務(wù)請(qǐng)求,所以一般情況需要工程師根據(jù)業(yè)務(wù)需求開發(fā)處理程序。

      5,視圖解析器查看resolver(不需要工程師開發(fā)),由框架提供

      6,視圖視圖(需要工程師開發(fā))

      查看是一個(gè)接口,實(shí)現(xiàn)類支持不同的視圖類型(JSP,F(xiàn)reeMarker的,PDF ...)

      注意:處理器處理程序(也就是我們平常說的控制器控制器)以及視圖層視圖都是需要我們自己手動(dòng)開發(fā)的其他的一些組件比如:前端控制器的DispatcherServlet,處理器映射器的HandlerMapping,處理器適配器的HandlerAdapter等等都是框架提供給我們的,不需要自己手動(dòng)開發(fā)。

      DispatcherServlet的詳細(xì)解析

      首先看下源碼:

      package?org.springframework.web.servlet;

      @SuppressWarnings("serial")

      public?class?DispatcherServlet?extends?FrameworkServlet?{

      public?static?final?String?MULTIPART_RESOLVER_BEAN_NAME?=?"multipartResolver";

      public?static?final?String?LOCALE_RESOLVER_BEAN_NAME?=?"localeResolver";

      public?static?final?String?THEME_RESOLVER_BEAN_NAME?=?"themeResolver";

      public?static?final?String?HANDLER_MAPPING_BEAN_NAME?=?"handlerMapping";

      public?static?final?String?HANDLER_ADAPTER_BEAN_NAME?=?"handlerAdapter";

      public?static?final?String?HANDLER_EXCEPTION_RESOLVER_BEAN_NAME?=?"handlerExceptionResolver";

      public?static?final?String?REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME?=?"viewNameTranslator";

      public?static?final?String?VIEW_RESOLVER_BEAN_NAME?=?"viewResolver";

      public?static?final?String?FLASH_MAP_MANAGER_BEAN_NAME?=?"flashMapManager";

      public?static?final?String?WEB_APPLICATION_CONTEXT_ATTRIBUTE?=?DispatcherServlet.class.getName()?+?".CONTEXT";

      public?static?final?String?LOCALE_RESOLVER_ATTRIBUTE?=?DispatcherServlet.class.getName()?+?".LOCALE_RESOLVER";

      public?static?final?String?THEME_RESOLVER_ATTRIBUTE?=?DispatcherServlet.class.getName()?+?".THEME_RESOLVER";

      public?static?final?String?THEME_SOURCE_ATTRIBUTE?=?DispatcherServlet.class.getName()?+?".THEME_SOURCE";

      public?static?final?String?INPUT_FLASH_MAP_ATTRIBUTE?=?DispatcherServlet.class.getName()?+?".INPUT_FLASH_MAP";

      public?static?final?String?OUTPUT_FLASH_MAP_ATTRIBUTE?=?DispatcherServlet.class.getName()?+?".OUTPUT_FLASH_MAP";

      public?static?final?String?FLASH_MAP_MANAGER_ATTRIBUTE?=?DispatcherServlet.class.getName()?+?".FLASH_MAP_MANAGER";

      public?static?final?String?EXCEPTION_ATTRIBUTE?=?DispatcherServlet.class.getName()?+?".EXCEPTION";

      public?static?final?String?PAGE_NOT_FOUND_LOG_CATEGORY?=?"org.springframework.web.servlet.PageNotFound";

      private?static?final?String?DEFAULT_STRATEGIES_PATH?=?"DispatcherServlet.properties";

      protected?static?final?Log?pageNotFoundLogger?=?LogFactory.getLog(PAGE_NOT_FOUND_LOG_CATEGORY);

      private?static?final?Properties?defaultStrategies;

      static?{

      try?{

      ClassPathResource?resource?=?new?ClassPathResource(DEFAULT_STRATEGIES_PATH,?DispatcherServlet.class);

      defaultStrategies?=?PropertiesLoaderUtils.loadProperties(resource);

      }

      catch?(IOException?ex)?{

      throw?new?IllegalStateException("Could?not?load?'DispatcherServlet.properties':?"?+?ex.getMessage());

      }

      }

      /**?Detect?all?HandlerMappings?or?just?expect?"handlerMapping"?bean??*/

      private?boolean?detectAllHandlerMappings?=?true;

      /**?Detect?all?HandlerAdapters?or?just?expect?"handlerAdapter"?bean??*/

      private?boolean?detectAllHandlerAdapters?=?true;

      /**?Detect?all?HandlerExceptionResolvers?or?just?expect?"handlerExceptionResolver"?bean??*/

      private?boolean?detectAllHandlerExceptionResolvers?=?true;

      /**?Detect?all?ViewResolvers?or?just?expect?"viewResolver"?bean??*/

      private?boolean?detectAllViewResolvers?=?true;

      /**?Throw?a?NoHandlerFoundException?if?no?Handler?was?found?to?process?this?request??**/

      private?boolean?throwExceptionIfNoHandlerFound?=?false;

      /**?Perform?cleanup?of?request?attributes?after?include?request??*/

      private?boolean?cleanupAfterInclude?=?true;

      /**?MultipartResolver?used?by?this?servlet?*/

      private?MultipartResolver?multipartResolver;

      /**?LocaleResolver?used?by?this?servlet?*/

      private?LocaleResolver?localeResolver;

      /**?ThemeResolver?used?by?this?servlet?*/

      private?ThemeResolver?themeResolver;

      /**?List?of?HandlerMappings?used?by?this?servlet?*/

      private?List?handlerMappings;

      /**?List?of?HandlerAdapters?used?by?this?servlet?*/

      private?List?handlerAdapters;

      /**?List?of?HandlerExceptionResolvers?used?by?this?servlet?*/

      private?List?handlerExceptionResolvers;

      /**?RequestToViewNameTranslator?used?by?this?servlet?*/

      private?RequestToViewNameTranslator?viewNameTranslator;

      private?FlashMapManager?flashMapManager;

      /**?List?of?ViewResolvers?used?by?this?servlet?*/

      private?List?viewResolvers;

      public?DispatcherServlet()?{

      super();

      }

      public?DispatcherServlet(WebApplicationContext?webApplicationContext)?{

      super(webApplicationContext);

      }

      @Override

      protected?void?onRefresh(ApplicationContext?context)?{

      initStrategies(context);

      }

      protected?void?initStrategies(ApplicationContext?context)?{

      initMultipartResolver(context);

      initLocaleResolver(context);

      initThemeResolver(context);

      initHandlerMappings(context);

      initHandlerAdapters(context);

      initHandlerExceptionResolvers(context);

      initRequestToViewNameTranslator(context);

      initViewResolvers(context);

      initFlashMapManager(context);

      }

      }

      DispatcherServlet的類中的屬性豆:

      ·????? HandlerMapping的:用于處理程序映射請(qǐng)求和一系列的對(duì)于-的前處理和后處理,大部分用@Controller注解。

      ·????? HandlerAdapter:幫助DispatcherServlet處理映射請(qǐng)求處理程序的適配器,而不用考慮實(shí)際調(diào)用的是哪個(gè)處理程序.- - -

      ·????? 視圖解析器:根據(jù)實(shí)際配置解析實(shí)際的視圖類型。

      ·????? ThemeResolver的:解決網(wǎng)絡(luò)應(yīng)用程序可以使用的主題,例如提供個(gè)性化布局。

      ·????? MultipartResolver:解析多部分請(qǐng)求,以支持從HTML表單上傳文件.-

      ·????? FlashMapManager:存儲(chǔ)并檢索可用于將一個(gè)請(qǐng)求屬性傳遞到另一個(gè)請(qǐng)求的輸入和輸出的FlashMap,通常用于重定向。

      在Web MVC框架中,每個(gè)DispatcherServlet都擁有自己的WebApplicationContext,它繼承了ApplicationContext.WebApplicationContext包含了其上下文和Servlet實(shí)例之間共享的所有的基礎(chǔ)框架bean。

      的HandlerMapping

      HandlerMapping的接口處理請(qǐng)求的映射的HandlerMapping接口的實(shí)現(xiàn)類:

      ·????? SimpleUrlHandlerMapping建立類通過配置文件把URL映射到控制器類。

      ·????? DefaultAnnotationHandlerMapping類通過注解把URL映射到控制器類。

      的HandlerAdapter

      的HandlerAdapter接口 - 處理請(qǐng)求映射

      AnnotationMethodHandlerAdapter上:通過注解,把請(qǐng)求URL映射到控制器類的方法上。

      HandlerExceptionResolver

      HandlerExceptionResolver接口 - 異常處理接口

      ·????? 的SimpleMappingExceptionResolver通過配置文件進(jìn)行異常處理。

      ·????? AnnotationMethodHandlerExceptionResolver:通過注解進(jìn)行異常處理。

      視圖解析器

      ViewResolver的接口解析查看視圖。

      UrlBasedViewResolver類通過配置文件,把一個(gè)視圖名交給到一個(gè)查看來處理。

      !本文整理自網(wǎng)絡(luò),原文出處暫不知,對(duì)原文做了較大的改動(dòng),在此說明整理人:JAVA團(tuán)長(zhǎng)

      MVC Spring

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:天津機(jī)械生產(chǎn)管理軟件(天津機(jī)械制造)
      下一篇:excel數(shù)字轉(zhuǎn)日期
      相關(guān)文章
      亚洲综合色自拍一区| 亚洲色中文字幕在线播放| ass亚洲**毛茸茸pics| 亚洲色图在线观看| 亚洲国产午夜电影在线入口| 亚洲jizzjizz少妇| 国产午夜亚洲不卡| 亚洲电影中文字幕| 狠狠亚洲狠狠欧洲2019| 久久综合亚洲色hezyo| WWW国产亚洲精品久久麻豆| 亚洲日韩一区精品射精| 亚洲性线免费观看视频成熟| 亚洲色精品aⅴ一区区三区 | ASS亚洲熟妇毛茸茸PICS| 亚洲精品麻豆av| 亚洲人成网77777色在线播放| 亚洲av成人中文无码专区| 亚洲系列中文字幕| 久久亚洲欧美国产精品| 久久综合久久综合亚洲| 亚洲国产精华液2020| 久久亚洲精品中文字幕无码| 亚洲精品无码专区久久| 亚洲熟妇久久精品| 亚洲天堂久久精品| 亚洲无码黄色网址| 亚洲视频在线一区二区三区| 亚洲中文字幕无码爆乳av中文 | 亚洲国产中文字幕在线观看| 国产91在线|亚洲| 亚洲精品国产精品国自产网站| 亚洲最大成人网色香蕉| 波多野结衣亚洲一级| 亚洲中文字幕久久精品无码A | 国产偷国产偷亚洲清高动态图 | 亚洲乱码国产一区网址| 亚洲乱码在线观看| 亚洲人成无码网站在线观看| 亚洲av无码专区国产不乱码| 亚洲aⅴ天堂av天堂无码麻豆|