博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringMVC原理探索,从DispatcherServlet开始
阅读量:4029 次
发布时间:2019-05-24

本文共 2525 字,大约阅读时间需要 8 分钟。

概述

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.

你可能感兴趣的文章
getpeername,getsockname
查看>>
让我做你的下一行Code
查看>>
浅析:setsockopt()改善程序的健壮性
查看>>
关于对象赋值及返回临时对象过程中的构造与析构
查看>>
VS 2005 CRT函数的安全性增强版本
查看>>
SQL 多表联合查询
查看>>
Visual Studio 2010:C++0x新特性
查看>>
drwtsn32.exe和adplus.vbs进行dump文件抓取
查看>>
cppcheck c++静态代码检查
查看>>
CLOSE_WAIT和TIME_WAIT
查看>>
在C++中使用Lua
查看>>
在Dll中调用自身的位图资源
查看>>
IP校验和详解
查看>>
C++中使用Mongo执行count和distinct运算
查看>>
一些socket的编程经验
查看>>
socket编程中select的使用
查看>>
C++获取文件大小常用技巧分享
查看>>
未来5年大机遇:做贩卖多巴胺的超级玩家
查看>>
关于AIS编码解码的两个小问题
查看>>
GitHub 万星推荐:黑客成长技术清单
查看>>