Spring MVC 是一套以 Servlet API 为基础平台的 Web 框架,一直是 Spring Framework 中重要的一个组成部分。与许多其他 Web 框架一样,Spring MVC 同样围绕前端页面的控制器模式 (Controller) 进行设计,其中最为核心的 Servlet —— DispatcherServlet 为来自客户端的请求处理提供通用的方法,而实际的工作交由可自定义配置的组件来执行。 这种模型使用方式非常灵活,可以满足多样化的项目需求。
前端控制器模式(Front Controller Pattern)是用来提供一个集中的请求处理机制,所有的请求都将由一个单一的处理程序处理
和任何普通的 Servlet 一样,DispatcherServlet 需要根据 Servlet 规范使用 Java 代码配置或在 web.xml 文件中声明请求和 Servlet 的映射关系。 DispatcherServlet 通过读取 Spring 的配置来发现它在请求映射、视图解析、异常处理等方面所依赖的组件。
DispatcherServlet 启动
- ServletContext 启动之后会调用 ContextLoaderListener 的 contextlnitialized 方法启动 WebApplicationContext 。
ContextLoaderListener 的作用是启动 Web 容器时,自动装配 ApplicationContext 的配置信 息。因为它实现了 ServletContextListener 这个接口,在 web.xml 配置这个监昕器,启动容器时, 就会默认执行它实现的方法,使用 ServletContextListener 接口,开发者能够在为客户端请求提 供服务之前向 ServletContext 中添加任意的对象。这个对象在 ServletContext 启动的时候被初始 化,然后在 ServletContext 整个运行期间都是可见的。
-
DispatcherServlet 初始化: 通过将当前的 servlet 类型实例转换为 BeanWrapper 类型 实例,以便使用 Spring 中提供的注入功能进行对应属性的注入。这些属性如contextAttribute 、 contextClass 、nameSpace 、contextConfigLocation 等,都可以在 web.xml 文件中以初始化参数的方式配置在 servlet 的声明中。DispatcherServlet 继承自FrameworkServlet, FrameworkServlet 类上包含对应的同名属性, Spring 会保证这些参数被注入到对应的值中。
- DispatcherServlet 补充初始化 WebApplicationContext
- 寻找或创建对应的 WebApplicationContext 实例
- 对已经创建的 WebApplicationContext 实例进行配置及刷新
- onRefresh 刷新 Spring 在 Web 功能实现中所必须使用的全局变量。
当 DispatcherServlet 载入后,它将从一个 XML 文件中载入 Spring 的应用上下文。
servlet 是一个 Java 编写的程序,此程序是基于 HttP 协议的,在服务器端运行的(如Tomcat ), 是按照 servlet 规范编写的一个 Java 类。主要是处理客户端的请求并将其结果发送到客户端。servlet 的生命周期是由 servlet 的容器来控制的,它可以分为3 个阶段:初始化、运行和销毁。
组件
View Resolver
View
ModelAndView
HandlerMappings
当客户端发出 Request 时 DispatcherServlet 会将 Request 提交给 HandlerMapping , 然后 HanlerMapping 根据 WebApplicationContext 的配置来回传给 DispatcherServlet 相应的Controller。
在基于 SpringMVC 的 Web 应用程序中,可以为 DispatcherServlet 提供多个 Handler Mapping 供其使用。DispatchServlet 在选用 HandlerMapping 的过程中, 将根据所指定的 一系列 HandlerMapping 的优先级进行排序, 然后优先使用优先级在前的 HandlerMapping 。如 果当前的 HandlerMapping 能够返回可用的 Handler, DispatcherServlet 则使用当前返回的Handler 进行 Web 请求的处理,而不再继续询问其他的 HandierMapping 。否则, DispatcherServlet 将继 续按照各个 HandlerMapping 的优先级进行询问, 直到获取一个可用的 Handler 为止。