7.SpringMVC流程及源码

425 阅读4分钟

思维导图:点击查看思维导图
文章图片:点击查看图片

SpringMVC 总体流程

整体流程图:www.processon.com/view/link/6…

image.png

1.前端控制器DispatcherServlet 作用:接收请求,进行请求分发,处理响应结果

2.处理映射器HandlerMapping 作用:根据请求URL,找到对应Handler

3.处理适配器HandlerAdapter 作用:调用处理器(Handler | Controller)

4.处理器Handler(即Controller,由我们自己开发) 作用:接收用户请求数据,调用业务处理

5.视图解析器ViewResolver 作用:视图解析

6.视图View(由前端人员开发) 作用:将数据展现给用户

MVC三大组件

处理器映射器

HandlerMapping 在 SpringMVC 容器启动时就已经注入到容器中了,哪个 URL 对应的执行链路是什么,适配器是什么,容器启动时就确定了。调用getHandler(HttpServletRequest request)方法会返回处理器的执行链HandlerExecutionChain,该类有两个重要属性:处理器 Object handler和 拦截器数组 HandlerInterceptor[] interceptors

image.png

image-20211226215722285.png

处理器适配器 HandlerAdapter

SpringMVC 使用适配器模式来适配调用 MVC 处理器 Handler。根据 Handler的不同种类采用不同的 Adapter。

Handler类别对应适配器描述使用
ControllerSimpleControllerHandlerAdapter标准控制器,返回ModelAndView实现 Controller 接口
HttpRequestHandlerHttpRequestHandlerAdapter业务自行处理请求,不返回ModeAndViewHttpRequestHandler 接口
ServletSimpleServletHandlerAdapter基于标准的 servlet 处理
HandlerMethodRequestMappingHandlerAdapter基于@requestMapping等注解对应方法处理注解@Controller 配置控制器

视图解析器 ViewResolver

视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给用户。为了实现视图模型和具体实现技术的解耦,SpringMVC 定义了一个高度抽象的 View 接口(视图)。它是无状态的(每一个请求都会创建一个 View),不存在线程安全问题。SpringMVC 中常用的视图类型有:URL 视图、JSON 视图、文档类视图、XML 视图。

ViewResolver 负责将处理结果生成 View 视图,先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。视图解析器的作用是将逻辑视图转为物理视图,所有的视图解析器都必须实现 ViewResolver 接口。

当然,有的场景也不需要视图解析器

  • 返回值是 String 类型,直接找到映射对应的 JSP,HTML,FreeMarker 或其他映射。默认请求是转发,也可以通过redirect 前缀指定为重定向
  • void(无返回值) ,因为我们在控制器方法的参数中可以直接使用原始 SerlvetAPI 对象 HttpServletRequest 和 HttpServletResponse 对象,所以无论是转发还是重定向都可以轻松实现,而无需使用返回值
  • ModeAndView 类型,不需要页面跳转,即基于 ajax 的异步请求,用 json 数据交互时,利用 @RequestBody 和 @ResponseBody 实现数据到 java 对象的绑定

参数获取

image-20211226222344275.png

拦截器

SpringMVC 中实现拦截器只需要继承HandlerInterceptorAdapter类,它间接的实现了 HandlerInterceptor接口

image.png

原理: 拦截器是通过Java反射机制 + JDK动态代理来实现的,因此必须依赖接口(拦截实现接口的类),SpringMVC 会从执行链中拿到拦截器数组后遍历,拿到所有的 HandlerInterceptor,执行对应阶段的方法,成功返回true放行,失败返回false拦截

实现: Spring实现拦截器只需要继承HandlerInterceptorAdapter类,并重写对应的方法

应用场景: 未登录用户拦截、日志审计等

自定义拦截器中三个方法:

  • preHandle => applyPreHandle(processedRequest, response) 控制器方法handle()执行之前
  • postHandle => applyPostHandle(processedRequest, response, mv) 在控制器方法handle()执行之后,结果视图创建生成之前
  • afterCompletion 结果视图创建生成之后,展示到浏览器之前。可以利用此方法进行清理操作

Spring整合SpringMVC注意事项

  • Bean 被创建两次: Spring 的 IOC 容器不应该扫描 SpringMVC 中的 bean, 对应的 SpringMVC 的 IOC 容器不应该扫描 Spring 中的 bean,可以配置对应容器只扫描自己需要的 bean
  • SpringIOC 容器与 SpringMVC 容器为父子关系,MVC 容器中能注入 IOC 容器的对象,反过来却不行 (例如:Controller 可以调 Service 但 Service 层不能注入 Controller)