Spring MVC 的核心组件
- DispatcherServlet:核心处理器(也叫前端控制器),负责调度其他组件的执行,可降低不同组件之间的耦合性,是整个 Spring MVC 的核心模块。
- Handler:处理器,完成具体业务逻辑,相当于 Servlet 或 Action。
- HandlerMapping:DispatcherServlet 是通过 HandlerMapping 将请求映射到不同的 Handler。
- HandlerInterceptor:处理器拦截器,是一个接口,如果我们需要做一些拦截处理,可以来实现这个接口。
- HandlerExecutionChain:处理器执行链,包括两部分内容,即 Handler和 HandlerInterceptor(系统会有一个默认的 HandlerInterceptor,如果需要额外拦截处理,可以添加拦截器设置)。
- HandlerAdapter:处理器适配器,Handler 执行业务方法之前,需要进行一系列的操作包括表单数据的验证、数据类型的转换、将表单数据封装到POJO 等,这一系列的操作,都是由 HandlerAdapter 来完成,DispatcherServlet 通过 HandlerAdapter 执行不同的 Handler。
- ModelAndView:装载了模型数据和视图信息,作为 Handler 的处理结果,返回给 DispatcherServlet。
ViewResolver:视图解析器,DispatcherServlet 通过它将逻辑视图解析成物理视图,最终将渲染结果响应给客户端。
Spring MVC 的执行流程
用户发送请求至前端控制器 DispatcherServlet。
- DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。
- 处理器映射器找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。
- DispatcherServlet 调用 HandlerAdapter 处理器适配器。
- HandlerAdapter 经过适配调用具体的处理器(Controller,也叫后端控制器)。
- Controller 执行完成返回 ModelAndView。
- HandlerAdapter 将 controller 执行结果 ModelAndView 返回给 DispatcherServlet。
- DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器。
- ViewReslover 解析后返回具体 View。
- DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中)。
- DispatcherServlet 响应用户。
Spring MVC 源码
1:首先方法进入:doDispatch
2:checkMultipart() 判断当前请求是否有文件
3:getHandler() :通过HandleMapping去找一个Controller对象
3.1:扩展点1:HandleMapping
3.2: Spring boot 扩展Spring mvc 其中就扩展了 HandleMapping 去解析静态资源
4: getHandlerAdapter(): 根据你controller的类型去找一个适配器
4.1: 因为Controller有很多种不同的注册方式 所以需要不同的适配器
4.2:扩展点2:HandlerAdapter
5:handle() : 执行Controller逻辑并且进行视图裁决(判断是要重定向还是转发还是响应页面)
5.1invokeForRequest():执行方法的全部逻辑
5.2:首先给参数赋值
5.2.1:参数赋值的扩展点:HandlerMethodArgumentResolver
5.3:调用invoke()指定方法
6:setResponseStatus()设置ResponseStatus响应状态码 对标:@ResponseStatus注解
7:handleReturnValue() 进行视图裁决
7.1:扩展点:returnValueHandlers 通过这个对象来进行判断接下来视图怎么做、
8:handler.handleReturnValue() 对冲顶于返回值处理(判断是否需要响应还是需要重定向)
8.1: 如果是@ResponseBody 注解又有一个扩展点:HttpMessageConverter
9:getModelAndView() 重新封装一个ModelAndView对象
9.1:如果不需要渲染视图(如果是重定向 || 响应视图的话) 就会返回null
9.2: mavContainer.isRequestHandled() 判断是否需要重定向或响应
9.3: 同时会把model里面的参数放到request.setAttribute(说明model的作用域是request作用域)
10:processDispatchResult():开始做视图渲染
10.1:判断是否需要响应异常视图
10.2:扩展点:ViewResolver
10.2:拿到视图名称 封装一个视图对象 进行forward