1 DispatcherServlet是前端控制器设计模式的实现,提供spring Web MVC的集中访问点,而且负责职责的分派。在web.xml中的配置:
<!-- Spring MVC servlet -->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 会在src目录下找SpringMVC配置文件 -->
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- 表示启动容器时初始化该Servlet; -->
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!-- 此处可以可以配置成*.do`-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
DispatcherServlet配置完成后,当相应的请求到达时,处理就开始了。 下面的列表描述了DispatcherServlet处理请求的全过程:
找到WebApplicationContext并将其绑定到请求的一个属性上, 以便控制器和处理链上的其它处理器能使用WebApplicationContext。 默认的属性名为DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE。
将本地化解析器(localResolver)绑定到请求上,这样使得处理链上的处理器在处理请求(准备数据、显示视图等等) 时能进行本地化处理。若不使用本地化解析器,也不会有任何副作用,因此如果不需要本地化解析,忽略它即可。
将主题解析器绑定到请求上,这样视图可以决定使用哪个主题。如果你不需要主题,可以忽略它,不会有任何影响。
如果上传文件解析器被指定,Spring会检查每个接收到的请求是否存在上传文件,如果存在, 这个请求将被封装成MultipartHttpServletRequest以便被处理链中的其它处理器使用 。
找到合适的处理器,执行和这个处理器相关的执行链(预处理器,后置处理器,控制器),以便为视图准备模型数据(用于渲染)。
如果模型数据被返回,就使用配置在WebApplicationContext中的视图解析器显示视图, 否则视图不会被显示。有多种原因可以导致返回的数据模型为空,比如预处理器或后处理器可能截取了请求,这可能是出于安全原因, 也可能是请求已经被处理,没有必要再处理一次。
请求处理过程中抛出的异常,可以被任何定义在WebApplicationContext中的异常解析器所获取。 使用这些异常解析器,可以在异常抛出时根据需要定义特定行为。
Spring的DispatcherServlet也支持返回Servlet API定义的last-modification-date。 决定某个请求的最后修改日期很简单:DispatcherServlet会首先寻找一个合适的handler mapping,检查从中取得指定的处理器是否实现了 LastModified接口,如果是,将调用long getLastModified(request)方法,并将结果返回给客户端。
以上摘自Springframework开发者文档。
查看源码可知:
/**
* Initialize the strategy objects that this servlet uses.
* <p>May be overridden in subclasses in order to initialize further strategy objects.
*/
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
/**
* Initialize the MultipartResolver used by this class.
* <p>If no bean is defined with the given name in the BeanFactory for this namespace,
* no multipart handling is provided.
*/
private void initMultipartResolver(ApplicationContext context) {
try {
this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
if (logger.isDebugEnabled()) {
logger.debug("Using MultipartResolver [" + this.multipartResolver + "]");
}
}
catch (NoSuchBeanDefinitionException ex) {
// Default is no multipart resolver.
this.multipartResolver = null;
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MultipartResolver with name '" + MULTIPART_RESOLVER_BEAN_NAME +
"': no multipart request handling provided");
}
}
}
未完待续。。。