1 SpringMVC的流程?

1:发起请求到前端控制器(DispatcherServlet)

2:前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找)

3:处理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象,多个HandlerInterceptor拦截器对象),通过这种策略模式,很容易添加新的映射策略

4:前端控制器调用处理器适配器去执行Handler

5:处理器适配器HandlerAdapter将会根据适配的结果去执行Handler

6:Handler执行完成给适配器返回ModelAndView

7:处理器适配器向前端控制器返回ModelAndView (ModelAndView是springmvc框架的一个底层对象,包括 Model和view)

8:前端控制器请求视图解析器去进行视图解析 (根据逻辑视图名解析成真正的视图(jsp)),通过这种策略很容易更换其他视图技术,只需要更改视图解析器即可

9:视图解析器向前端控制器返回View

10:前端控制器进行视图渲染

2主要组件说明

首先,我们得说出每个组件是做什么的,当然要每个单词读出来最好。DispatcherServlet:

spring mvc的入口,整个框架运行就是在这个servlet中完成。

HandlerMapping:处理器映射起。用于映射每个处理方法对应的请求路径。是一个map结构

handler:处理器。实际上就是控制器中的每个处理方法。

HandlerAdapter:处理器适配器。专门用来调用handler,因为在spring mvc中每个处理方法参数以及返回类型都不一样,因此需要用适配器来适配。

ViewResovler:视图解析器。用于指定视图技术,以及视图技术相关的配置。

View:视图。springmvc 中支持多种视图,除了jsp外 还有xml,json,pdf等。

3 SpringMVC的优点

1.清晰的角色划分:控制器(controller)、验证器(validator)、命令对象(command obect)、表单对象(form object)、模型对象(model object)、Servlet分发器(DispatcherServlet)、处理器映射(handler mapping)、试图解析器(view resoler)等等。每一个角色都可以由一个专门的对象来实现。

2.强大而直接的配置方式:将框架类和应用程序类都能作为JavaBean配置,支持跨多个context的引用,例如,在web控制器中对业务对象和验证器validator)的引用。

3.可适配、非侵入:可以根据不同的应用场景,选择何事的控制器子类(simple型、command型、from型、wizard型、multi-action型或者自定义),而不是一个单一控制器(比如Action/ActionForm)继承。

4.可重用的业务代码:可以使用现有的业务对象作为命令或表单对象,而不需要去扩展某个特定框架的基类。

5.可定制的绑定(binding)和验证(validation):比如将类型不匹配作为应用级的验证错误,这可以保证错误的值。再比如本地化的日期和数字绑定等等。在其他某些框架中,你只能使用字符串表单对象,需要手动解析它并转换到业务对象。

6.可定制的handler mapping和view resolution:Spring提供从最简单的URL映射,到复杂的、专用的定制策略。与某些web MVC框架强制开发人员使用单一特定技术相比,Spring显得更加灵活。

7.灵活的model转换:在Springweb框架中,使用基于Map的键/值对来达到轻易的与各种视图技术集成。

8.可定制的本地化和主题(theme)解析:支持在JSP中可选择地使用Spring标签库、支持JSTL、支持Velocity(不需要额外的中间层)等等。

9.简单而强大的JSP标签库(Spring Tag Library):支持包括诸如数据绑定和主题(theme)之类的许多功能。他提供在标记方面的最大灵活性。

10.JSP表单标签库:在Spring2.0中引入的表单标签库,使用在JSP编写表单更加容易。

11.Spring Bean的生命周期:可以被限制在当前的HTTp Request或者HTTp Session。准确的说,这并非Spring MVC框架本身特性,而应归属于Spring MVC使用的WebApplicationContext容器。

4 源码分析

1 DispatherServlet 入口

4 spring mvc - 图1
DispatherServlet本身就是HttpServlet,满足Servlet规范。入口为diDisapatch

2 HandlerMapping

3 参数解析器

1

2 Servlet API

ServletRequestMethodArgumentResolver 用来解析这些参数,control类里面的WebRequest、ServletRequest、MultipartRequest、 HttpSession、javax.servlet.http.PushBuilder、Principal、InputStream、Reader、HttpMethod、Locale、TimeZone、ZoneId以上的部分参数。

  1. @Override
  2. public boolean supportsParameter(MethodParameter parameter) {
  3. Class<?> paramType = parameter.getParameterType();
  4. return (WebRequest.class.isAssignableFrom(paramType) ||
  5. ServletRequest.class.isAssignableFrom(paramType) ||
  6. MultipartRequest.class.isAssignableFrom(paramType) ||
  7. HttpSession.class.isAssignableFrom(paramType) ||
  8. (pushBuilder != null && pushBuilder.isAssignableFrom(paramType)) ||
  9. Principal.class.isAssignableFrom(paramType) ||
  10. InputStream.class.isAssignableFrom(paramType) ||
  11. Reader.class.isAssignableFrom(paramType) ||
  12. HttpMethod.class == paramType ||
  13. Locale.class == paramType ||
  14. TimeZone.class == paramType ||
  15. ZoneId.class == paramType);
  16. }

4 数据响应与内容协商

15 种返回值解析器
4 spring mvc - 图2

类型的返回值:
1 ModelAndView
2 Model
3 View
4 ResponseEntity
5 ResponseBodyEmitter
6 StreamingResponseBody
7 HttpEntity
8 HttpHeaders
9 Callable 异步
10 DeferredResult
11 ListenableFuture 异步
12 CompletionStage springmvc异步编程
13 WebAsyncTask 异步任务
14 有 @ModelAttribute 且为对象类型的
15 @ResponseBody 注解 —-> RequestResponseBodyMethodProcessor;

4.1数据响应 -数据

1 响应JSON、xml

1 返回值解析器
ackson.jar+@ResponseBody
RequestResponseBodyMethodProcessor来处理@ResponseBody的注解。

2 返回值解析器原理

• 1、返回值处理器判断是否支持这种类型返回值 supportsReturnType
• 2、返回值处理器调用 handleReturnValue 进行处理
• 3、RequestResponseBodyMethodProcessor 可以处理返回值标了@ResponseBody 注解的。
• 4. 利用 MessageConverters 进行处理 将数据写为json
•• 1、内容协商(浏览器默认会以请求头的方式告诉服务器他能接受什么样的内容类型)
•• 2、服务器最终根据自己自身的能力,决定服务器能生产出什么样内容类型的数据,
•• 3、SpringMVC会挨个遍历所有容器底层的 HttpMessageConverter ,看谁能处理?
•••1、得到MappingJackson2HttpMessageConverter可以将对象写为json
•••2、利用MappingJackson2HttpMessageConverter将对象转为json再写出去。

——————-HttpMessageConverter

2、内容协商

根据客户端接收能力不同,返回不同媒体类型的数据
2、postman分别测试返回json和xml
只需要改变请求头中Accept字段。Http协议中规定的,告诉服务器本客户端可以接收的数据类型。
3、开启浏览器参数方式内容协商功能
为了方便内容协商,开启基于请求参数的内容协商功能。

  1. spring:
  2. contentnegotiation:
  3. favor-parameter: true #开启请求参数内容协商模式

发请求: http://localhost:8080/test/person?format=json
http://localhost:8080/test/person?format=xml

同时存在 format指定的优先级更高

4.2 web页面

5 拦截逻辑

https://www.cnblogs.com/zhshlimi/p/9671273.html
https://blog.csdn.net/weixin_46469945/article/details/109510230
https://www.cnblogs.com/itfeng813/p/13026652.html

参考

1 https://www.yuque.com/atguigu/springboot/vgzmgh