要使用Sping MVC,只需要在 web.xml 中配置一个 DispatcherServlet :
12 7dispatcherServlet 34 org.springframework.web.servlet.DispatcherServlet 5 68 dispatcherServlet 9/* 10
再定义一个 dispatcherServlet-servlet.xml 配置文件:
12 3 4 155 96 8demo 710 13 1416 17 18 22 2319 21org.springframework.web.servlet.view.InternalResource-View 2024 2825 27/demo.html26
这样一个简单的基于Spring MVC 的应用就创建完成了。
Spring MVC 的使用非常简单,如上述代码所示我们只要扩展一个路径映射关系;定义一个视图解析器;在定义一个业务逻辑的处理流程规划,Spring MVC 就能够帮我们完成所有的MVC功能了。
DispatcherServlet 类相关结构图:
DispatcherServlet 类继承了 HttpServlet,在 Servlet 的 init 方法调用时 DispatcherServlet 执行 Spring MVC 的初始化工作。DispatcherServlet 初始化什么,可以在其 initStrategies 方法中知道,如图所示:
initMultipartResolver:初始化 MultipartResolver ,用于处理文件上传服务,如果有文件上传,那么会将当前的 HttpServletRequest包装成 DefaultMultipartHttpServletRequest ,并且将每个上传的内容封装成 CommonsMultipartFile 对象。
initLocaleResolver:用于处理应用的国际化问题,通过解析请求的 Locale 和设置响应的 Locale 来控制应用中的字符编码问题。
initThemeResolver:用于定义一个主题,例如,可以根据用户的喜好来设置用户访问页面的样式,可以将这个样式作为一个 Theme Name 保存,保存在用于请求来的Cookie 中或者保存在服务端的 Session 中,以后每次请求根据这个 Theme Name 返回特定的内容。
initHandlerMappings:用于定义用户设置的请求映射关系,例如,前面示例中的 SimpleUrlHandlerMapping 把用于用户请求的 URL 映射成一个个 Handler 实例。对 HandlerMapping 必须定义,如果没有定义,将获取 DispatcherServlet.properties 文件中默认的两个 HandlerMapping,分别是 BeanNameUrlHandlerMapping 和DefaultAnnotationHandlerMapping。
initHandlerAdapters:用于根据 Handler 的类型定义不同的处理规则,例如,定义 SimpleControllerHandlerAdapter 处理所有的 Controller 实例对象,在 HandlerMapping 中将 URL 映射成一个 Controller 实例,那么 Spring MVC在解析时 SimpleControllerHandlerAdapter 就会调用这个 Controller 实例。同样对HandlerAdapters 也必须定义,如果没有定义,将获取 DispatcherServlet.properties 文件中默认的4个 HandlerAdapters,分别是 HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、ThrowawayControllerHandlerAdapter和AnnotationMethodHandlerAdapter。
initHandlerExceptionResolvers:当 Handler 处理出错时,会通过这个 Handler 来统一处理,默认的实现类是 SimpleMappingExceptionResolver,将错误日志记录在log文件中,并且转到默认的错误页面。
initRequestToViewNameTranslator:将指定的 ViewName 按照定义的 RequestToViewNameTranslator 替换成想要的格式,如加上前缀或者后缀等。
initViewResolvers:用于将 view 解析成页面,在 viewResolvers 中可以设置多个解析策略,如可以根据 JSP 来解析,或者按照 Velocity 模板解析。默认的解析策略是InternalResourceViewResolver,按照 JSP 页面来解析。
从上面的初始化策略可以看出,在一个请求中可能需要我们来扩展的地方都定义了扩展点,只要实现相关的接口类,并创建一个 Spring Bean 就能扩展 Spring MVC 框架。
在 Spring MVC 框架中,有3个组件是用户必须要定义和扩展的:定义 URL 映射规则、实现业务逻辑的 Handler 实例对象、渲染模板资源。而连接 Handler 实例对象和模板渲染的纽带就是 Model 模型了。
下面看看 DispatcherServlet 在启动时都做了哪些事情?
HttpServlet 初始化调用了 HttpServletBean 的init() 方法,该方法的作用是获取 Servlet 中的 init 参数,并创建一个 BeanWrapper 对象,然后由子类处真正执行 BeanWrapper 的初始化工作。但是 HttpServletBean 的子类 FrameworkServlet 和 DispatcherServlet 都没有覆盖其 initBeanWrapper(bw) 方法,所以创建的 BeanWrapper 对象没有任何作用,Spring 容器也不是通过 BeanWrapper 来创建的。
Spring 容器的创建是在 FrameworkServlet 的 initServletBean() 方法中完成的,这个方法会创建 WebApplicationContext 对象,并调用其 refresh() 方法来完成配置文件的加载,配置文件的加载同样先是查找 Servlet 的init-param 参数中设置的路径,如果没有,会根据namespace+Servlet 的名称来查找 XML 文件。Spring 容器在加载时会调用 DispatcherServlet 的 initStrategies 方法来完成在 DispatcherServlet 中定义的初始化工作。在 initStrategies 方法中会初始化 Spring MVC 框架需要的8个组件,这8个组件对应的8个 Bean 对象都保存在 DispatcherServlet 类中。
Spring MVC初始化时序图如图所示:
这时 DispatcherServlet 已经初始化完成,Spring MVC 也已经初始化完成,可以接受HTTP请求了。
--《深入分析Java Web技术内幕修订版》 Page 365-Page 369