elasticsearch入門系列">elasticsearch入門系列
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
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
/**?List?of?HandlerAdapters?used?by?this?servlet?*/
private?List
/**?List?of?HandlerExceptionResolvers?used?by?this?servlet?*/
private?List
/**?RequestToViewNameTranslator?used?by?this?servlet?*/
private?RequestToViewNameTranslator?viewNameTranslator;
private?FlashMapManager?flashMapManager;
/**?List?of?ViewResolvers?used?by?this?servlet?*/
private?List
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)容。