springmvc的原理是什么,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。
青秀網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),青秀網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為青秀超過(guò)千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的青秀做網(wǎng)站的公司定做!
一、spring mvc 設(shè)計(jì)思想與體系結(jié)構(gòu)組成
知識(shí)點(diǎn)
jsp 執(zhí)行過(guò)程回顧
spring mvc執(zhí)行流程解析
mvc 體系結(jié)構(gòu)
1、回顧servlet 與jsp 執(zhí)行過(guò)程
流程說(shuō)明:
請(qǐng)求Servlet
處理業(yè)務(wù)邏輯
設(shè)置業(yè)務(wù)Model
forward jsp Servlet
jsp Servlet 解析封裝html 返回
提問(wèn):這個(gè)是一個(gè)MVC應(yīng)用場(chǎng)景嗎?
spring mvc本質(zhì)上還是在使用Servlet處理,并在其基礎(chǔ)上進(jìn)行了封裝簡(jiǎn)化了開(kāi)發(fā)流程,提高易用性、并使用程序邏輯結(jié)構(gòu)變得更清晰
基于注解的URL映謝
http表單參數(shù)轉(zhuǎn)換
全局統(tǒng)一異常處理
攔截器的實(shí)現(xiàn)
2、spring mvc 執(zhí)行流程:
整個(gè)過(guò)程是如何實(shí)現(xiàn)的?
dispatchServlet 如何找到對(duì)應(yīng)的Control?
如何執(zhí)行調(diào)用Control 當(dāng)中的業(yè)務(wù)方法?
回答這些問(wèn)題之前我們先來(lái)認(rèn)識(shí)一下spring mvc 體系結(jié)構(gòu)
3、spring mvc 體系結(jié)構(gòu)
HandlerMapping'h?ndl? 'm?p??
url與控制器的映謝
HandlerAdapter 'h?ndl? ?'d?pt?
控制器執(zhí)行適配器
ViewResolvervju? ri?'z?lv?
視圖倉(cāng)庫(kù)
view
具體解析視圖
HandlerExceptionResolver 'h?ndl? ?k'sep?(?)n ri?'z?lv?
異常捕捕捉器
HandlerInterceptor 'h?ndl? ?nt?'sept?
攔截器
配置一個(gè)spring mvc 示例演示 驗(yàn)證上述流程
創(chuàng)建一個(gè)Controller 類
配置DispatchServlet
創(chuàng)建spring-mvc.xml 文件
配置SimpleUrlHandlerMapping
配置InternalResourceViewResolver
體系結(jié)構(gòu)UML
二、mvc 執(zhí)行流程解析
知識(shí)點(diǎn):
mvc 具體執(zhí)行流程
HandlerMapping詳解
HandlerAdapter 詳解
ViewResolver與View詳解
HandlerExceptionResolver詳解
HandlerInterceptor 詳解
mvc 各組件執(zhí)行流程
2、HandlerMapping 詳解
其為mvc 中url路徑與Control對(duì)象的映射,DispatcherServlet 就是基于此組件來(lái)尋找對(duì)應(yīng)的Control,如果找不到就會(huì)報(bào)Not Found mapping 的異常。
HandlerMapping 接口方法
HandlerMapping 接口結(jié)構(gòu)
目前主流的三種mapping 如下:
BeanNameUrlHandlerMapping: 基于ioc name 中已 "/" 開(kāi)頭的Bean時(shí)行 注冊(cè)至映謝.
SimpleUrlHandlerMapping:基于手動(dòng)配置 url 與control 映謝
RequestMappingHandlerMapping:基于@RequestMapping注解配置對(duì)應(yīng)映謝
演示基于 BeanNameUrlHandlerMapping 配置映謝。
編寫(xiě)mvc 文件
<!--簡(jiǎn)單控制器-->
<bean id="/user.do" class="com.tuling.mvc.control.BeanNameControl"/>
// beanname control 控制器
public class BeanNameControl implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
request.getRequestDispatcher("/WEB-INF/page/userView.jsp").forward(request, response);
}
}
當(dāng)IOC 中實(shí)例化這些類之后 DispatcherServlet 就會(huì)通過(guò)org.springframework.web.servlet.DispatcherServlet#getHandler() 方法基于request查找對(duì)應(yīng)Handler。 但找到對(duì)應(yīng)的Handler之后我們發(fā)現(xiàn)他是一個(gè)Object類型,并沒(méi)有實(shí)現(xiàn)特定接口。如何調(diào)用Handler呢?
3、HandlerAdapter詳解
這里spring mvc 采用適配器模式來(lái)適配調(diào)用指定Handler,根據(jù)Handler的不同種類采用不同的Adapter,其Handler與 HandlerAdapter 對(duì)應(yīng)關(guān)系如下:
Handler類別 | 對(duì)應(yīng)適配器 | 描述 |
Controller | SimpleControllerHandlerAdapter | 標(biāo)準(zhǔn)控制器,返回ModelAndView |
HttpRequestHandler | HttpRequestHandlerAdapter | 業(yè)務(wù)自行處理 請(qǐng)求,不需要通過(guò)modelAndView 轉(zhuǎn)到視圖 |
Servlet | SimpleServletHandlerAdapter | 基于標(biāo)準(zhǔn)的servlet 處理 |
HandlerMethod | RequestMappingHandlerAdapter | 基于@requestMapping對(duì)應(yīng)方法處理 |
HandlerAdapter 接口方法
HandlerAdapter 接口結(jié)構(gòu)圖
演示基于Servlet 處理 SimpleServletHandlerAdapter
<!-- 配置控制器 -->
<bean id="/hello.do" class="com.tuling.mvc.control.HelloServlet"/>
<!-- 配置適配器 -->
<bean class="org.springframework.web.servlet.handler.SimpleServletHandlerAdapter"/>
// 標(biāo)準(zhǔn)Servlet
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("hello luban ");
}
}
上述例子中當(dāng)IOC 中實(shí)例化這些類之后 DispatcherServlet 就會(huì)通過(guò)
org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter() 方法查找對(duì)應(yīng)handler的適配器 ,如果找不到就會(huì)報(bào) No adapter for handler 。
4、ViewResolver 與View 詳解
找到應(yīng)的Adapter 之后就會(huì)基于適配器調(diào)用業(yè)務(wù)處理,處理完之后業(yè)務(wù)方會(huì)返回一個(gè)ModelAndView ,在去查找對(duì)應(yīng)的視圖進(jìn)行處理。其在org.springframework.web.servlet.DispatcherServlet#resolveViewName() 中遍歷 viewResolvers 列表查找,如果找不到就會(huì)報(bào)一個(gè) Could not resolve view with name 異常。
在下一步就是基于ViewResolver.resolveViewName() 獲取對(duì)應(yīng)View來(lái)解析生成Html并返回 。對(duì)應(yīng)VIEW結(jié)構(gòu)如下:
至此整個(gè)正向流程就已經(jīng)走完了,如果此時(shí)程序處理異常 MVC 該如何處理呢?
5、HandlerExceptionResolver詳解
該組件用于指示 當(dāng)出現(xiàn)異常時(shí) mvc 該如何處理。 dispatcherServlet 會(huì)調(diào)用org.springframework.web.servlet.DispatcherServlet#processHandlerException() 方法,遍歷 handlerExceptionResolvers 處理異常,處理完成之后返回errorView 跳轉(zhuǎn)到異常視圖。
演示自定義異常捕捉
public class SimpleExceptionHandle implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
return new ModelAndView("error");
}
}
<!-- 演示異常配置 -->
<bean class="com.tuling.mvc.control.SimpleExceptionHandle"/>
HandlerExceptionResolver 結(jié)構(gòu)
除了上述組件之外 spring 中還引入了 我Interceptor 攔截器 機(jī)制,類似于Filter。
6、HandlerInterceptor 詳解
演示HandlerInterceptor
public class SimpleHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
<!--配置interceptor 組件-->
<bean class="com.tuling.mvc.control.SimpleHandlerInterceptor"></bean>
其實(shí)現(xiàn)機(jī)制是基于 HandlerExecutionChain 分別在 doDispatch 方法中執(zhí)行以下方法:
preHandle :業(yè)務(wù)處理前執(zhí)行
postHandle:業(yè)務(wù)處理后(異常則不執(zhí)行)
afterCompletion:視圖處理后
具體邏輯源碼參見(jiàn):org.springframework.web.servlet.DispatcherServlet#doDispatch 方法。
三、注解配置
演示基于注解配置mvc mapping
<context:component-scan base-package="com.tuling.mvc.control" />
<!-- 注解驅(qū)動(dòng) -->
<mvc:annotation-driven/>
<!-- 視圖倉(cāng)庫(kù) -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/" />
<property name="suffix" value=".jsp" />
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
</bean>
// 注解方法
@RequestMapping("/hello.do")
public ModelAndView hello() {
ModelAndView mv = new ModelAndView("userView");
mv.addObject("name", "luban");
return mv;
}
提問(wèn) 為什么基于 <mvc:annotation-driven/> 配置就能實(shí)現(xiàn)mvc 的整個(gè)配置了,之前所提到的 handlerMapping 、與handlerAdapter 組件都不適用了?
只要查看以類的源就可以知曉其中原因:
認(rèn)識(shí) NamespaceHandler 接口
查看 MvcNamespaceHandler
查看AnnotationDrivenBeanDefinitionParser
結(jié)論:
在<mvc:annotation-driven /> 對(duì)應(yīng)的解析器,自動(dòng)向ioc 里面注冊(cè)了兩個(gè)BeanDefinition。分別是:RequestMappingHandlerMapping與BeanNameUrlHandlerMapping
關(guān)于springmvc的原理是什么問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
網(wǎng)頁(yè)名稱:springmvc的原理是什么
網(wǎng)站地址:http://www.chinadenli.net/article34/jcocpe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、動(dòng)態(tài)網(wǎng)站、網(wǎng)站改版、全網(wǎng)營(yíng)銷推廣、定制開(kāi)發(fā)、標(biāo)簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)