SpringMVC框架源码解析

这篇blog是学完itheima视频后进一步学习的内容,所以也是紧接着上一篇blog:
https://blog.csdn.net/qq_43175022/article/details/108933556

源码分析

雷丰阳大神讲解https://www.bilibili.com/video/BV1d4411g7tv?p=156

组件解析 的前四步及九大组件
  1. p156 流程分析

在这里插入图片描述

  1. p157 -160 doDispatch()方法源码分析SpringMVC加载过程,对应上文组件解析前7个步骤的内容
  • 157 源码分析,找到有用方法加注解
  • 158 文字概述上述过程:

在这里插入图片描述

​ 解析getHandler()方法,引出:getHandler()方法如何根据当前请求找到对应类来处理,即如何返回目标处理类的执行链(同组件解析的第③步)

​ 解决:通过调用HandlerMapping(处理器映射器)保存每一个处理器对应处理的请求映射信息

  • 159 解析getHandlerAdapter()方法,解析如何找到适配器Adapter,对应④⑤步

    三种返回值类型的获取方法:

    HTTPRequestHandlerAdapter()、

    SimpleControllerHandlerAdapter()、

    AnnotationMethodHandlerAdapter()注解适配器,重点

  • 160 后续Debug走完组件解析的后续两步

  1. p161 SpringMVC九大组件:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

(没有翻译的那个不重要),九大组件作用及共同点:

在这里插入图片描述

  1. p162 九大组件初始化细节:

在这里插入图片描述

细节:

在这里插入图片描述

例如HandlerMapping组件:

在这里插入图片描述

总结:

在这里插入图片描述

组件解析中的关键点Handler处理 P163-167
  1. p163 聚焦组件解析中⑤⑥步中Handler的目标方法执行:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

引出真正执行的方法:

在这里插入图片描述

  1. p164 invokeHandlerMethod()方法解析,真正执行目标方法的两个注解(34点)的解析:
  • 首先查找34点中的是否有@SessionAttributes存储Session,没有直接执行下一步:

    在这里插入图片描述

  • 进入@ModelAttribute注解解析细节:

    在这里插入图片描述

  • 进入resolveHandlerArguments()方法,获得agrs[]:

    在这里插入图片描述

    • 该方法使用一个双层for()循环确定:

    在这里插入图片描述

    在这里插入图片描述

    • 然后进行分支判断找到的注解个数(由于上述注解冲突只能标一个,出现多个就抛出异常):

    在这里插入图片描述

    • 分析没有找到注解的分支:

    在这里插入图片描述

    • 进入resolveCommonArgument()方法解析普通参数(原生API):

      确定当前参数是否为Servlet原生API,解析成功就将方法返回的Object赋予上文声明的args[]

    • 不为普通参数时:

      在这里插入图片描述

      本例中为map参数,所以传入隐含模型

  • 获得args[] (该args只获得ModelAttribute注解这一个参数)后,寻找ModelAttribute注解属性Value的值,赋予attrName

    在这里插入图片描述

  • 反射Method类型的attributeMethodToInvoke(由for循环迭代遍历获得的attributeMethod解析而来),使其可访问

  • 运行ModelAttribute提前运行的方法(详情可见34点)赋予一个Object类型

    在这里插入图片描述

  • 判断上述attrName是否为空

    • 不为空上述方法已经赋值

    • 为空执行下列语句:

      在这里插入图片描述

      赋予ModelAttribute方法的返回值类型首字母小写(由attributeMethodToInvoke获得)

  • 判断隐含模型是否包含attrName,没有就执行:

    在这里插入图片描述

    作用:

    在这里插入图片描述

  • 再次调用resolveHandlerArguments()方法,获得agrs[]:

    不同的是第一个形参换成了 invokeHandlerMethod()方法的第一个形参handleMethod解析获得的handlerMethodToInvoke

  • return语句:

    真真正正的执行方法:handlerMethodToInvoke.invoke

总结:ModelAttribute标注的方法提前运行并且把执行后的返回值放在隐含模型中

  1. p165 166 上文有提及,40点只是获取了34点的两个提前注解的参数信息,所以需要再次调用resolveHandlerArguments()方法,获取其他参数的值
  • 165 @RequestParam的普通类型、普通类型、map类型的三个参数获得流程:

    在这里插入图片描述

  • 166 POJO类型(自定义类型)参数:

    • 有注解:

      在这里插入图片描述

    • 没注解:

      在这里插入图片描述

    总结:

    在这里插入图片描述

    步骤:

    • 该方法的内循环的一个分支语句,确定上述值:

      在这里插入图片描述

    • 进入resolveModelAttribute()方法获取WebDataBinder实例对象:

      在这里插入图片描述

    • 标红部分讲解,确定POJO的值:

      在这里插入图片描述

  1. 上述166 167Handler处理获得参数过程总结(排除两个提前注解过程):

    在这里插入图片描述

    在这里插入图片描述

组件解析的视图解析部分(最后三步)源码分析
  1. p172 视图解析流程:

在这里插入图片描述

结合代码重点摘要:

在这里插入图片描述

在这里插入图片描述

上述图片流程解析:

完成了上文Handler处理获得ModelAndView对象后,继续向下执行调用了上述第2点processDispatchResult()方法,该方法方法体中调用了第3点的render()方法渲染页面,该方法中声明View(页面)对象,View调用前端控制器定义的resolveNameView()方法,获得一个View对象,提出下面第5点问题:

  • 组件解析中的⑧⑨步的视图解析器调用源码流程解析:

    在这里插入图片描述

    • 在前端控制器的resolveNameView()方法中,迭代遍历九大组件之一的ViewResolver对象

      在这里插入图片描述

      过程中还查看当前viewResolver对象的获得方法和默认值

    • 迭代出的当前页面的视图解析器调用本身接口自带的内部resolveNameView()方法,获得一个View对象:

      在这里插入图片描述

      进入该resolveViewName()方法(在一个抽象类中):

      • 首先查看缓存,有就直接获取

      • 为空时调用createView()方法创建View对象:

        在这里插入图片描述

        View对象:

        在这里插入图片描述

        进入createView()方法:

        • 三个不同类型的分支结构判断创建获得其中一种View对象:

          在这里插入图片描述

        • 调用父类执行创建,父类再调用loadView()方法一顿解析,期间又会返回createView()方法所在类进行解析(略)

      • 获得一个View对象

        本案例中获得了一个InternalResourceView对象

        还有一个常用的View对象:RedirectView对象

      • 存入缓存

    • 上述流程总结:

      在这里插入图片描述

  • 组件解析中的⑩步的视图解析器调用源码流程解析:

    上述得到View对象后返回第三点的render()方法(前端控制器定义的)

    • view对象调用接口自带的内部render()方法(抽象类中)(上文接口图示可见该方法):

      在这里插入图片描述

    • 进入renderMergedOutputModel()方法:

      其中的关键方法exposeModelAsRequestAttribute():

      在这里插入图片描述

    • 进入exposeModelAsRequestAttribute()方法:

      在这里插入图片描述

    • 回到renderMergedOutputModel()方法:

      取得映射地址并获得转发器:

      在这里插入图片描述

      转发器转发:

      在这里插入图片描述

    如果获得的View对象是RedirectView对象,就是获得重定向器,重定向到映射地址。

  • 总结:

    在这里插入图片描述

拦截器和异常处理源码 P211 212和P221 226 4P

略。

猜你喜欢

转载自blog.csdn.net/qq_43175022/article/details/108957419