概述
SpringMVC框架围绕着DispatcherServlet而设计,实现Web请求到处理器的转发,支持配置URL到处理器的映射,视图的解析,国际化和时区,主题解析还有文件上传功能。采用基于@Controller和@RequestMaping注解作为默认处理器,提供非常灵活的处理方法。随着Spring3.0的发布,@Controller的机制还允许通过@PathVariable注解来创建REFTful风格的Web应用程序。
Spring Web MVC的核心设计理念为开闭原则,即对扩展开放,对修改关闭。设计者口中对DispatcherServlet的描述为:
Http请求道Handler处理器(控制器)的中心转发器,然后把请求分发到已注册的用于处理Web请求的处理器上。此外,还提供便利的映射和异常处理功能。
本身是一个非常灵活的Servlet,可用于任何工作流,接入任何适恰的适配器类,其如下的功能与其他基于请求的Web MVC框架泾渭分明。
1. 基于JavaBean的配置机制
2. 可采用任何HandlerMapping的任何实现类作为构建程序的一部分,并以此控制请求道处理器对象的路由。在springmvc中,默认为
BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping 作为实现类,HandlerMapping对象可以成Servlet上下文中的Bean,而且还可以赋予其任何名称
3. 允许使用任何 HandlerAdapter.默认适配器为HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter.分别是为HttpRequestHandler、Controller接口适配.同时,还将注册一个默认的AnnotationMethodHandlerAdapter.HandlerAdapter对象也可以以Bean的形式添加到应用程序上下文中,并可指定任何名称
4. 以HandlerExceptionResolver接口作为异常处理策略,用以实现具体异常到错误页面的映射
5. 以ViewResolve的实现类作为视图处理策略,用以把逻辑视图名称解析成视图对象
6. 若springmvc不支持用户定义的视图,则使用RequestToViewNameTranslator来完成视图转换
7. 用 MultipartResolver的实现类来处理复合请求(处理文件上传)
8. 用LocaleResolver作为国际化处理方案
9. 用ThemeResolver作为主题解析方案
web程序中可以定义多个DispatcherServlet,每个Servlet操作自己的命名空间,加载自己的上下文环境,只有ContextLoaderListener加载的根上下文可以被共享
请求处理过程
当用户发起一次请求时,从离开用户的浏览器到返回响应时,此段旅程经过几个站点,每次都是留下一些信息然后又携带一下信息。如图描述所示[图来源至Craig Walls–Spring in Action Fourth Edition]
对于部署在Tomcat中的Web应用程序来说,其启动入口为web.xml。因此,请求的第一站会被配置在web.xml文件中的DispatcherServlet接收,就像多数Java Web框架一样,在SpringMVC中,所有的请求都经过一个前端控制器Servlet。前端控制器模式是常用的Web应用程序模式,在这里一个单实例的Servlet将请求委托给应用程序的其他来执行实际的处理。而此处的DispatcherServlet就是一个前端控制器。
DispatcherServlet的工作是发送请求到后台Controller中,
controller
是一种处理请求的spring组件。在典型的应用中,有多个controller组件,DispatcherServlet需要决定发送到具体的controller中,因此会查询一个或多个处理器映射,然后决定请求到达的具体的下一站。处理器映射会根据请求所携带的URL信息来进行决策。一旦选择了合适的控制器,DispatcherServlet会将请求发送给选中的控制器。到达了控制器,请求会卸下其负载信息(用户提交的信息),并耐心的等到控制器处理这些信息(事实上设计良好的控制器本身只处理很少甚至不处理工作,而是将业务逻辑委派给一个或多个Service对象)
控制器处理完成业务逻辑后,通常会生成一些信息,这些信息需要返回给用户并在其浏览器上显示。这些信息被称为模型(model),不过仅仅给用户返回原始的信息是不够的–这些信息需要以用户友好的方式进行格式化,一般是HTML。因此,这些信息需要发送给给视图(View),通常是Jsp或Velocity。
控制器所做的最后一件事是模型数据打包,并标识出用于渲染输出的视图名称。然后接下来会将请求模型和视图名称发送会DispatcherServlet。
这样控制器就不会与特定的视图相耦合,传递给DispatcherServlet的视图名称并不直接表示某个特定的JSP, 事实上它甚至不能确定视图就是JSP。相反,它仅仅传递了一个逻辑名称,这个名称将会用来查找生成结果真正视图。DispatcherServlet将会使用视图解析器来讲逻辑视图名匹配为一个特定的视图实现,它可能是也可能不是JSP。
到此时,DispatcherServlet已经知道由哪个视图渲染结果,那么请求的任务基本也就完了。它的最终站是视图的实现(可能是JSP),在这里它交付模型数据,请求的任务就完成了。视图将使用模型数据渲染输出,并通过这个输出将对象传递给客户端。
DispatcherServlet类图
在IntelliJ IDEA 中打开其源码,然后右键查看Diagrams,工具会自动生成其类图。
可是直观的看出,DispatcherServlet本质上是Servlet.