spring mvc -- DispatcherServlet

Spring的web mvc框架跟其他web mvc框架一样,请求驱动,围绕一个中心Servlet设计。Servlet分发请求到控制器,并且提供其他功能,使得web应用开发便捷。但是,Spring的DispatcherServlet做的不仅仅是这些,它整合了Spring的IoC容器,这样我们就可以使用Spring其它特点。

Spring Web MVC DispatcherServlet请求处理流如下表所示。

spring mvc -- DispatcherServlet

DispatcherServlet实际上是Servlet,它继承了HttpServlet基类。如果你希望由DispatcherServlet处理请求,那么你需要通过一个URL映射请求。以下是在Servlet 3.0+环境中一个标准的Java EE Servlet配置:

spring mvc -- DispatcherServlet

 在上面的例子中,所有以/example开头的请求都会被名称为example的DispatcherServlet实例所处理。

WebApplicationInitializer是由Spring MVC提供的接口,用来确保基于代码的配置能够被探测,同时用来初始化任何Servlet 3 容器。该接口的抽象基类实现是AbstractAnnotationConfigDispatcherServletInitializer。该抽象类通过简单定义servlet maping以及列出配置类就能够注册DispatcherServlet,它是设置Spring MVC应用常推荐的方式。

DispatcherServlet实际上是Servlet,所以需要在应用的web.xml中进行定义。你需要映射你希望DispatcherServlet处理的请求,通过在web.xml文件中适用URL mapping。这也是标准JavaEE Servlet的配置,如下的例子展示了如何定义和映射DispatcherServlet。

spring mvc -- DispatcherServlet

 在Web MVC框架中,每一个DispatcherServlet都有它自己的WebApplicationContext。WebApplicationContext继承了所有已经定义在root WebApplicationContext中的beans。root WebApplicationContext应当包含所有的基础beans,这些beans可以在其他上下文或者Servlet实例中使用。这些继承的beans可以在servlet范围内重载,你也可以在给定的Servlet示例中创建新的beans。

spring mvc -- DispatcherServlet

 DispatcherServlet初始化时,Spring MVC会在应用的WEB-INF目录下查找名称为[servlet-name]-servlet.xml文件,并且创建所有在该文件中定义的beans。如果该文件的bean在全局其他地方有定义过,那么会覆盖全局的bean定义。

 假若在web.xml文件中有如下的DispatcherServlet配置:

spring mvc -- DispatcherServlet

   在上图的Servlet配置中,你需要有一个名称为/WEB-INF/golfing-servlet.xml文件;这个文件包含你的Spring Web MVC组件(beans)。通过Servlet初始化参数,你可以修改配置文件的路径。对于只有单个DispatcherServlet场景,只有一个root context是有可能的。如下图所示:

spring mvc -- DispatcherServlet

 这个可以通过设置一个空的contextConfigLocation servlet初始化参数来配置,如下图所示:

 spring mvc -- DispatcherServlet

  WebApplicationContext是ApplicationContext的扩展,它包含了对于web应用来说需要的额外功能。它不同于普通的ApplicationContext,具有resolving themes能力,同时也知道它关联的Servlet。WebApplicationContext绑定ServletContext,通过使用RequestContextUtils类的静态方法,你也可以查询WebApplicationContext,如果你需要的话。

1. 在WebApplicationContext中的特殊Bean类型

    Spring DispatcherServlet使用特殊的beans来处理请求,提供合适的视图。这些beans是Spring MVC的一部分。通过在WebApplicationContext中配置一个或者多个特殊beans,你可以选择使用何种特殊beans。但是,起初你并不需要做这些,因为如果你没有配置任何bean,Spring MVC会管理一批默认的beans来使用。在下一节会详细介绍。首先来看下DispatcherServlet依赖的特殊beans。

spring mvc -- DispatcherServlet

2. 默认的DispatcherServlet配置

  正如前面所提到,DispatcherServlet对于每一个特殊的bean维护了其默认实现列表。这些信息维护org.springframework.web.servlet包下的DispatcherServlet.properties文件里。

   所有特殊beans都有其合理的默认实现。尽管迟早你需要为这些beans自定义一个或多个配置文件。比如,配置一个InternalResourceViewResolver来对所有视图文件的父位置定义前缀属性是十分常见的。

    配置Spring MVC有其他一些选择,如MVC Java配置和MVC XML命名空间,这两者都提供了一个简单的开始起点,并且不需要你非常了解Spring MVC如何工作。

3. DispatcherServlet处理顺序

    当你设置好了DispatcherServlet后,一个请求进入到指定的DispatcherServlet,DispatcherServlet处理请求的过程如下: 

    1. 查询WebApplicationContext,并把WebApplicationContext绑定到请求上,作为一个属性。控制器或者其他元素可能会在处理过程中使用到。WebApplicationContext会绑定到属性名为DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE,默认情况下;

    2. locale resovler绑定到请求上,使得元素能够在处理过程中解决locale,比如提供视图,准备数据等等。如果你不需要locale resolving,那么你就不需要用这个;

    3. theme resoler绑定到请求上,使得元素,比如视图,能够决定使用哪个主题。如果你不需要使用主题,忽略它;

  4. 如果你定义了特定的multipart file resolver, 请求会检查multiparts; 如果multiparts找到了,请求会被包装成MultipartHttpServletRequest,以便后续处理;

    5. 查找合适的处理器。如果处理器找到了,执行链会关联这个处理器(preprocessors, postprocessors, controllers),并被执行以准备或者提供模型;

    6. 如果模型返回了,视图就提供了;如果没有模型返回(可能是由于preprocessors或者postprocessors拦截了这个请求,或者是安全原因),没有视图可提供。

    处理器异常resolvers可以在WebApplicationContext中声明,这样在处理的过程中,如果有异常抛出则可捕获。使用这些异常resolvers允许你定义一些通用的行为来解决异常问题。

    Spring DispatcherServlet同样也支持返回最后修改时间,由Servlet API提供。确定一个特定请求的最后修改时间的处理过程是十分直接的:DispatcherServlet查询一个合适的处理器映射,然后测试是否该处理器实现了LastModified接口。如果实现了,那么直接调用LastModified接口的long  getLastModified(request)方法获取最后修改时间并返回给客户端。

     你也可以自定义个人的DispatcherServlet实例,通过在web.xml文件中增加Servlet初始化参数(init-param标签)到Servlet定义。以下是DispatcherServlet初始化参数。

   spring mvc -- DispatcherServlet