一、SpringMVC 概念
1.1 什么是MVC
MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式
● Model(模型):处理应用程序数据逻辑的部分
● View(视图):处理数据显示的部分
● Controller(控制器):处理与用户交互的部分
示例流程图如下:
1.2 SpringMVC 设计模式
1.2.1 改进
SpringMVC 将传统的 Model 层再次进行细化,拆分为 Service 层和 Dao层
● Service(业务层):处理业务逻辑代码
● Dao(数据访问层):处理数据库操作
1.2.2 设计模型图
可以看到,Spring 是 SpringMVC 的父容器,SpringMVC 为子容器
1.2.3 SpringMVC 组件解析
| 组件 | 组件名 | 作用 |
| 前端适配器 | DispatcherServlet | 相当于mvc模式中的c。它是整个流程控制的中心,由它调用其他组件处理用户的请求,相当于组件的控制中枢。它的存在降低了组件之间的耦合性。 |
| 处理器映射器 | HandlerMapping | 负责根据用户请求找到对应的处理器Handler(处理类和方法)。Spring提供了不同的映射器实现不同的映射方式,如:配置文件方式、实现接口方式、注解方式等。 |
| 处理器 | Handler | 即具体业务控制器,当 DispatcherServlet 将用户的请求转发到 Handler, 由 Handler 对具体的用户请求进行处理 |
| 处理器适配器 | HandlerAdapter | 通过 HandlerAdapter 对处理器进行执行,可以通过扩展适配器实现对更多类型的处理器的执行 |
| 视图解析器 | View Resolver | 负责将 Handler 处理的结果生成 View 视图,View Resolver 先根据逻辑视图名解析成物理视图名(即具体的页面地址),再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。 |
| 视图 | View | 展现给用户的界面 |
1.2.4 SpringMVC 模型图和流程分析
模型图如下:
流程为:
- 用户先进行 http 请求,请求被 DispatcherServlet(前端控制器) 拦截
- DispatcherServlet(前端控制器) 根据实际配置,选择将请求发送到 HandlerMapping(处理器映射器) 或是直接放过(静态资源)
- HandlerMapping(处理器映射器) HandlerMapping 根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet
- DispatcherServlet 获取到映射器的返回数据,发送给 HandlerAdapter(处理器适配器),让他调用对应的 Handler 处理业务
- HandlerAdapter 将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView 对象(包含模型数据、逻辑视图名)
- Handler 处理完将结果 ModelAndView 返回给 HandlerAdapter,HandlerAdapter 将 ModelAndView 返回给 DispatcherServlet
- DispatcherServlet 将 ModelAndView 发送给 ViewResolver(视图解析器)进行解析
- ViewResolver 解析后返回具体的 View 给DispatcherServlet
- DispatcherServlet 对 View 进行渲染(即填充数据到视图中),并响应给用户
从上面的流程分析,有几个关键点:
1. 拦截器什么时候生效?
拦截器生效是在HandlerAdapter 找到真正的处理器,即将对 Handler 处理时,先执行拦截器
2. HandlerAdapter 有什么作用?
在 HandlerMapping 时就已经找到了请求对应的执行方法,那么为什么还要 HandlerAdapter呢?
这是由于不同的 Handler 对应了不同的处理器,处理器类型分别为:
| HandleAdapter实现类 | 请求处理器类型 | 介绍 |
| RequestMappingHandlerAdapter | HandlerMethod | 每个HandlerMethod对应一个@RequestMapping注解的控制器方法 |
| HttpRequestHandlerAdapter | HttpRequestHandler |
HttpRequestHandler的例子比如静态资源请求处理器
|
| ResourceHttpRequestHandler | Controller | 请求处理器是实现了接口 Controller的某个对象 |
1.2.5 SpringMVC 有什么优势
- 支持各种视图技术,不仅仅局限于jsp
- 与 Spring 框架无缝结合,能够使用 IOC、AOP等
- 支持各种请求的映射策略(RequestMapper)
- 代码结构更加清晰,利于多人共同开发、功能拓展和维护
1.2.6 SpringMVC 与 Strust2 比较
共同点:
● 框架
SpringMVC 和 Strust2 都是基于 MVC 的表现层框架
● 请求处理
SpringMVC 和 Strust2 都是一个核心控制器
● 线程安全
SpringMVC 默认通过单例模式创建 Controller Bean,即并发请求下用的是同一个实例,当没有共享属性时是线程安全的,也不应该在 Controller、Service、Dao 内创建共享属性!
而 Strust2 对每一个请求分配一个新的 action 实例处理,故也是线程安全的
区别:
● 入口
SpringMVC 的入口是 Servlet,Strust2 的入口是 Filter。但Filter在容器启动后就初始化,服务停止后销毁,晚于Servlet;Servlet在是在调用时初始化,先于Filter调用,服务停止后销毁。
● 拦截机制
SpringMVC 是方法级别的拦截,一个方法对应一个 Request 上下文,所以方法都是独立的,独享 request、response 数据。且每个方法和一个url对应,传递的参数是直接注入到方法中的,是方法独有的。
Strust2 是类级别的拦截。每一次请求都会创建一个 Action,通过 ActionBean 的 setter 和 getter 方法将数据注入到属性中。由于是通过属性接收的,故属性参数是让类中的多个方法共享的。
● 性能
由于 SpringMVC 中使用了单例模式,没有重复创建 Controller Bean 的消耗,而 Strust2 的每个 Action 都需要重新创建对象,即多例模式,故 SpringMVC 的性能略优于 Strust2
● 配置
由于 SpringMVC 与 Spring 的配置是无缝的,基本使用注解就可以完成配置,而 Strust2 需要通过 xml 文件配置