在web.xml中配置
<servlet>
<servlet-name>citic</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/frm-servlet.xml,/WEB-INF/app-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
先看繼承關係:
public class DispatcherServlet extends FrameworkServlet
public abstract class FrameworkServlet extends HttpServletBean
public abstract class HttpServletBean extends HttpServlet
知道最終繼承的是javax.servlet.http.HttpServlet類,大家都知道在初始化一個Servlet的時候會默認調用定義的int()方法,所有肯定我們要在這個方法上做文章,這個方法在HttpServletBean 中重寫。
類中的重要代碼如下:
@Override
public final void init() throws ServletException {
// 交給子類FrameworkServlet 實現
initServletBean();
到FrameworkServlet 中initServletBean內部代碼:
this.webApplicationContext = initWebApplicationContext();
initFrameworkServlet();
protected WebApplicationContext initWebApplicationContext() {
onRefresh(wac);
}
好了,onRefresh是最終要在我們接觸到的類DispatcherServlet中實現的方法,直接定位DispatcherServlet類的內部代碼。
@Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
/**
* Initialize the strategy objects that this servlet uses.
* <p>May be overridden in subclasses in order to initialize further strategy objects.
* <p>這是最終執行的方法刷新,,它是在WebApplicationContext已經存在的情況下進行的,也就意味着在初始化它的時候,
* IOC容器應該已經工作了,這也是我們在web.xml中配置Spring的時候,需要把DispatcherServlet的 load-on-startup的屬性配置爲2的原因。
*/
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
////初始化Handler映射,例如@RequestMapping(value = "/something", method = RequestMethod.PUT)
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
哦了,看到這麼多初始化我們就放心了,因爲這裏的每一個方法都是Spring的大牛之處,其中不乏大量的使用註解的聲明方式(註解的分享在Spring註解一文說明)
下面我們來一個一個的分享下上面的一系列init操作。
&& initMultipartResolver(context)
作用:初始化Spring的文件上傳解析器。
private void initMultipartResolver(ApplicationContext context) {
this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
只是簡單的從ApplicationContext (相當於bean工廠)得到需要類型的對象。
&&initLocaleResolver(context)
web應用程序支持國際化,必須識別每個用戶的首選區域,並根據這個區域顯示內容。
在Spring MVC應用程序中,用戶的區域是通過區域解析器來識別的,它必須實現LocaleResolver接口(在Spring-LocaleResolver中詳細講解)。
private void initLocaleResolver(ApplicationContext context) {
this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
…………
catch (NoSuchBeanDefinitionException ex) {
// We need to use the default.
this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
這裏注意如果沒有會得到默認的localeResolver ,定義實在屬性文件DispatcherServlet.properties中org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
就是AcceptHeaderLocaleResolver類
&&ThemeResolver主題解析
初始化過程和上面的LocaleResolver方式是一樣的,如果沒有定義會得到默認配置的org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
&&initHandlerMappings
作用:初始化與用戶請求相關聯的控制器
// 這裏找到所有在上下文中定義的HandlerMapping,同時把他們排序
// 因爲在同一個上下文中可以有不止一個handlerMapping,所以我們把他們都載入到一個鏈裏進行維護和管理
Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
很簡單,就是從bean工廠得到給定類型的所有的bean。Spring中默認定義的爲BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping
*Spring是怎樣加載用戶定義的HandlerMapping將在《Spring MVC-HandlerMapping》中分享,點擊這裏前往Spring MVC-HandlerMapping
&&initHandlerAdapters
作用:處理用戶的請求。
HandlerMappings是找到用戶的請求對應的處理類和函數,HandlerAdapter任務是執行找到的函數,在執行之前有一系列的初始化操作。
Spring中默認定義的爲HandlerAdapter爲HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、AnnotationMethodHandlerAdapter
*Spring是怎樣加載用戶定義的HandlerAdapter將在《Spring MVC-HandlerAdapter》中分享,點擊網址前往Spring MVC-HandlerAdapter
&& initHandlerExceptionResolvers
作用:初始化異常解析器,就是在handle請求的時候對於產生的異常如何處理,其實就是對response對象的設置,還有就是返回ModelAndView對象。
*Spring是怎樣加載用戶定義的HandlerAdapter將在《Spring MVC-HandlerExceptionResolver》中分享,點擊網址前往Spring MVC-HandlerExceptionResolver
&& initRequestToViewNameTranslator
作用:將請求轉換爲對應的視圖名稱
Spring中默認定義的爲HandlerAdapter爲AnnotationMethodHandlerExceptionResolver、ResponseStatusExceptionResolver和DefaultHandlerExceptionResolver。
Spring是怎樣加載用戶定義的HandlerAdapter將在《Spring MVC-RequestToViewNameTranslator》中分享
&&initViewResolvers(context)
作用:視圖解析
Spring中默認定義的爲ViewResolver爲InternalResourceViewResolver
Spring是怎樣加載用戶定義的HandlerAdapter將在《Spring MVC-ViewResolver》中分享