Spring3.1.0實現原理分析(十二).MVC核心類DispatcherServlet初始化過程

大家好,今天我們分析下DispatcherServlet的初始化過程,下面的配置大家一定不陌生吧,只要使用spring mvc框架大多會在web.xml文件中加入這麼一段配置,可見這個類是spring mvc的核心類,就是由它負責處理request請求的,在DispatcherServlet的初始化過程中也會創建web容器,結合上篇博客的內容,這裏創建的web容器就是子web容器,而它的父web容器就是在ContextLoaderListener中創建的根web容器。
<servlet>
	<servlet-name>petclinic</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>


先上一張類結構圖,DispatcherServlet還有兩個超類,它們各自負責實現初始化過程中某部分功能。

     


我們來分析下這個圖。

        最上面的抽象類HttpServletBean派生自HttpServlet,說明它是一個servlet類,另外它還實現了spring的EnvironmentAware接口,說明它具備獲取一個環境對象的能力。HttpServletBean本身有個成員變量environment,它的默認值是StandardServletEnvironment對象,既然都已擁有了環境對象爲什麼還要實現這個接口呢?目的應該是讓用戶有擴展的機會,比如用戶可以編寫一個StandardServletEnvironment的派生類,然後把這個類賦值HttpServletBean。對於spring環境對象沒概念的朋友,可以看下這篇博客《Spring3.1.0實現原理分析(三).配置數據》

HttpServletBean重寫了GenericServlet的init()方法,這個方法是servlet初始化的入口方法。HttpServletBean在這個方法中負責把用戶配置的servlet參數“init-param”賦值給本類成員變量,用戶可以在web.xml爲DispatcherServlet配置哪些初始化參數呢,大致有如下,

  • String contextId: web容器Id,如果用戶未配置spring自動生成。
  • String namespace: 命名空間,如果未配置就是servletname。
  • String contextConfigLocation: servlet配置文件地址,如果用戶未配置默認是/WEB-INF/+namespace+.xml
  • boolean publishEvents :是否在每次請求結束後發佈一個ServletRequestHandledEvent對象,默認true,如果修改成false據說能提升性能。
  • boolean dispatchOptionsRequest :是否處理OPTIONS請求,默認false。
  • boolean dispatchTraceRequest:是否處理TRACE請求,默認false。
  • String contextInitializerClasses:配置容器初始化器類型,多個用逗號分隔,用戶可以通過編寫容器初始化器對web容器執行擴展操作。

       

      接着來看FrameworkServlet類,HttpServletBean把用戶配置的初始化參數賦值給成員變量後,會調用一個空方法initServletBean(),然後派生類FrameworkServlet就通過重寫該方法繼續初始化工作。FrameworkServlet類主要負責創建子web容器,會把在ContextLoaderListener中創建的根web容器作爲父容器賦值給子web容器,然後把子web容器置入servletContext的屬性集,key是“org.springframework.web.servlet.FrameworkServlet.CONTEXT.”+servletName。web容器會通過重寫傳統容器的postProcessBeanFactory(beanFactory)方法,在創建過程中增加些額外處理,這個在上篇博客中也有論述
       

       最後是DispatcherServlet類,在FrameworkServlet把子web容器置入SC之前,會調用本類一個空方法onRefresh(web容器),DispatcherServlet通過重寫這個方法繼續初始化操作。DispatcherServlet主要職責是“初始化策略對象”。什麼是策略對象呢?就是一組spring默認的,用來實現MVC框架各種功能的實現類。比如像文件上傳、URL映射、異常處理、視圖解析等功能,針對不同的功能spring有專門的實現類,正如Spring官網對自己MVC框架的評價“職責分離”。這些默認的策略對象有部分被配置在DispatcherServlet.properties文件中,這個文件的全路徑是“org\springframework\web\servlet\DispatcherServlet.properties”。那麼具體會在DispatcherServlet類中初始化哪些策略對象呢,有如下。

  1. 文件上傳解析器 : 這個用戶必須在spring servlet配置文件中顯示配置,否則爲null。
  2. 本地化對象解析器 : 默認值是AcceptHeaderLocaleResolver。
  3. 主題解析器 :默認值是FixedThemeResolver。
  4. URL映射解析器:有RequestMappingHandlerMapping,BeanNameUrlHandlerMapping。這兩個不是配置在DispatcherServlet.properties文件中,而是用戶如果配置了<mvc:annotation-driven />,spring自動註冊的。
  5. 處理器適配器:有RequestMappingHandlerAdapter,HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter,AnnotationMethodHandlerAdapter。這幾個也是spring自動註冊。
  6. 異常解析器:有ExceptionHandlerExceptionResolver,ResponseStatusExceptionResolver,DefaultHandlerExceptionResolver,SimpleMappingExceptionResolver。這幾個也是spring自動註冊。
  7. 視圖名稱轉換器:默認值是DefaultRequestToViewNameTranslator。
  8. 視圖解析器:有ContentNegotiatingViewResolver,BeanNameViewResolver,InternalResourceViewResolver,也是spring自動註冊。
  9. 閃屬性管理器:默認值是DefaultFlashMapManager。
上述各個對象其實就是spring mvc框架的核心類,我會在後續博客中逐一分析。最後強調下,在ContextLoaderListener中創建的web容器叫根web容器,而DispatcherServlet初始化過程中創建的web容器,是其子容器,可以在web.xml文件中配置多個DispatcherServlet,那麼就會有多個子web容器,但是根web容器只有一個。

      

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章