<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類中初始化哪些策略對象呢,有如下。
- 文件上傳解析器 : 這個用戶必須在spring servlet配置文件中顯示配置,否則爲null。
- 本地化對象解析器 : 默認值是AcceptHeaderLocaleResolver。
- 主題解析器 :默認值是FixedThemeResolver。
- URL映射解析器:有RequestMappingHandlerMapping,BeanNameUrlHandlerMapping。這兩個不是配置在DispatcherServlet.properties文件中,而是用戶如果配置了<mvc:annotation-driven />,spring自動註冊的。
- 處理器適配器:有RequestMappingHandlerAdapter,HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter,AnnotationMethodHandlerAdapter。這幾個也是spring自動註冊。
- 異常解析器:有ExceptionHandlerExceptionResolver,ResponseStatusExceptionResolver,DefaultHandlerExceptionResolver,SimpleMappingExceptionResolver。這幾個也是spring自動註冊。
- 視圖名稱轉換器:默認值是DefaultRequestToViewNameTranslator。
- 視圖解析器:有ContentNegotiatingViewResolver,BeanNameViewResolver,InternalResourceViewResolver,也是spring自動註冊。
- 閃屬性管理器:默認值是DefaultFlashMapManager。