1.springmvc 的配置
1.1 web.xml
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置springMVC需要加載的配置文件
spring-dao.xml,spring-service.xml,spring-web.xml
Mybatis - > spring -> springmvc
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-*.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<!-- 默認匹配所有的請求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
值的注意的是contextConfigLocation和DispatcherServlet(用此類來攔截請求)的引用和配置。
1.2 spring-web.xml
<!-- 配置SpringMVC -->
<!-- 1.開啓SpringMVC註解模式 -->
<!-- 簡化配置:
(1)自動註冊DefaultAnootationHandlerMapping,AnotationMethodHandlerAdapter
(2)提供一些列:數據綁定,數字和日期的format @NumberFormat, @DateTimeFormat, xml,json默認讀寫支持
-->
<mvc:annotation-driven />
<!-- 2.靜態資源默認servlet配置
(1)加入對靜態資源的處理:js,gif,png
(2)允許使用"/"做整體映射
-->
<mvc:default-servlet-handler/>
<!-- 3.配置jsp 顯示ViewResolver -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 4.掃描web相關的bean -->
<context:component-scan base-package="com.xxx.fantj.web" />
值的注意的是InternalResourceViewResolver,它會在ModelAndView返回的試圖名前面加上prefix前綴,在後面加載suffix指定後綴。
SpringMvc主支源碼分析
引用《Spring in Action》中的一張圖來更好的瞭解執行過程:
上圖流程總體來說可分爲三大塊:
- Map<url,Controller>的建立(並放入WebApplicationContext)
- HttpRequest請求中Url的請求攔截處理(DispatchServlet處理)
- 反射調用Controller中對應的處理方法,並返回視圖
詳細流程總結:
- 1.客戶端發起一個請求,發向dispatcherServlet(前端控制處理器)
- 前端控制處理器首先初始化各種策略(initMultipartResolver,initViewResolvers,initHandlerMappring,initHandlerAdapter)
- 2.前端控制處理器利用接收到的request遍歷HandlerMapping集合(Map<url,controller>)
- 3.找到對應的HandlerMapping,並得到HandlerExecutionChain,HandlerExecutionChain內部包括了攔截器
- HandlerMapping核心實現類:RequestMappingHandlerMapping ,作用:找出Spring容器中被@controller註解修飾的bean,以及被@RequestMapping註解修飾的類和方法
- 4.HandlerInterceptor攔截調用preHandler方法,然後使用HandlerexecutionChain中的Handler遍歷HandlerAdapter集合,找到支持此Handler的HandlerAdapter
- 5.使用HandlerAdapter得到ModelAndView,然後HandlerInterceptor攔截調用postHandler方法
- HandlerAdapter核心實現類:RequestMappingHandlerAdapter
-
解析方法的參數:RequestMappingHandlerAdapter內部使用HandlerMethodArgumentResolverComposite對象處理該對象內部擁有HandlerMethodArgumentResolver集合:實現類:1.RequestParamMethodArgumentResolver處理@RequestParam註解修飾的參數;2.RequestResponseBodyMethodProcessor:@處理@RequestBody註解修飾的參數
- 處理方法的返回值:RequestMappingHandlerAdapter內部使用HandlerMethodReturnValueHandlerComposite對象處理該對象內部擁有HandlerMethodReturnValueHandler集合,實現類:1.RequestResponseBodyMethodProcessor處理@responseBody註解修飾的返回值;2.ModelAndViewMethodReturnValueHandler:處理返回值類型爲ModelAndView的方法
- 6.異常處理,前面四個步驟可能發生異常,使用HandlerExceptionResolve策略解決
- 7.根據返回的ModelAndView使用viewResolver進行解析
- 8.ViewResolver解析得到View返回給瀏覽器顯示
本文將圍繞這三塊進行分析。