首页 > 代码库 > Spring MVC:DispatcherServlet
Spring MVC:DispatcherServlet
DispatcherServlet是SpringMVC的前端控制器,换句话说它是SpringMVC的入口。即所有的请求都要经过它才能流转,所以称它为中央控制器也是可以的。这篇博客想要讲的是,它作为中央控制器是如何流转或者说分发请求的。
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc.xml,classpath:config/applicationContext-common.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
以上是DispatcherServlet的配置,和平常的Servlet配置没什么差别。从servlet-mapping的配置知道,它拦截了所有请求。当然,springMVC允许配置多个DispatcherServlet,只是每一个都会带着自己的WebApplicationContext也就是对应的处理请求的bean的配置,里面主要是Controller,HandlerMapping,ViewResolver。这里这么说可能还是不知道我说什么,我们继续往下看。
初始化的源码如下:
protected void initStrategies(ApplicationContext context){
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
initStrategies()方法会在DispatcherServlet对应的WebApplicationContext初始化后自动执行,此时DispatcherServlet上下文中的Bean已经初始化完毕。该方法的工作事先通过一定的发现机制查询上下文中的组件Bean,如果找不到则装配默认的组件实例。
Spring MVC定义了一套默认的组件实现类,也就是说即使不在Spring容器中显式配置组件Bean,也会有一套可用的默认组件出现在DispatcherServlet中。Spring在spring.jar包的org/springframework/web/servlet类路径定义了一个DispatcherServlet.properties配置文件,在其中指定了组件的默认实现类。
# Default implementation classes for DispatcherServlet‘s strategy interfaces. # Used as fallback when no matching beans are found in the DispatcherServlet context. # Not meant to be customized by application developers. org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping, org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter, org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter, org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver, org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver, org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
这里还有一个比较重要的内容就是WebApplicationContext的层次关系。全局的WebApplicationContext与DispatcherServlet的WebApplicationContext之间是父子关系,子可以获取到,覆写父中定义的Bean,反之不行。也就是说,DispatcherServlet享有了Spring提供的服务。或者说它继承了Spring的一切特性。
DispatcherServlet组件说明
这部分可以对应着SpringMVC的基本流程图来看,其中①上传文件解析器 ②本地化解析器 ③主题解析器 图里没有体现,除了上传文件解析器知道是上传文件使用的,剩下两个目前也还没有查它们什么功能。这里就结合图说说相关的其他解析器的作用。
HandlerMapping
首先,我们知道真正处理请求的Bean,也就是Controller都是在WebApplicationContext容器里面的。这个HandlerMapping的作用就是根据你的请求地址,去容器中获取对应的Controller的。我们可以指定HandlerMapping,如果没有指定就默认使用使用BeanNameUrlHandlerMapping实现类。
HandlerAdapter
HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;如SimpleControllerHandlerAdapter将对实现了Controller接口的Bean进行适配,并且掉处理器的handleRequest方法进行功能处理;
ViewResolver
ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;如InternalResourceViewResolver将逻辑视图名映射为jsp视图
小结:DispatcherServlet作为中央控制器,它通过持有了WebApplicationContext就持有了所有它工作所需要的Bean。剩下的就是根据请求去获得或者组装需要的处理器就好了。
参考:
http://blog.csdn.net/zhuojiajin/article/details/46280007
Spring MVC:DispatcherServlet