springMVC的执行过程

今天学完springMVC,大致总结一下它的工作流程

 博客内容较长,请耐心看完

1.  用户向服务器发送请求,请求被前端控制器捕获,前端控制器对请求资源路径进行解析,判断请求对应的映射。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 

(1)当未找到请求映射的时候,并且未配置mvc:default-servlet-handler,会报如下错误。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 

 由自己配置的前端控制器输出报错信息。

(2)当未找到请求映射的时候并且配置了mvc:default-servlet-handler,会报如下错误

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 由springMVC自己的默认处理器输出报错信息。

2. 找到请求映射的时候。映射处理器获取该handler配置的相关对象,最后以执行链对象返回。我们先进入到前端控制器的doDispatch方法。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 

(1)有三个成员变量,第一个handler 是请求对应的控制器方法,第二个是拦截器集合,第三个是拦截器下标

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 (2)点进getHandler方法

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Li65LuA5LmI6KaB5a2m57yW56iL,size_20,color_FFFFFF,t_70,g_se,x_16

(3) 可以看到有一个handlerMappings成员变量

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Li65LuA5LmI6KaB5a2m57yW56iL,size_20,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Li65LuA5LmI6KaB5a2m57yW56iL,size_20,color_FFFFFF,t_70,g_se,x_16

 可以看到有五个handlerMapping,相当于这5个挨个进去比较watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Li65LuA5LmI6KaB5a2m57yW56iL,size_20,color_FFFFFF,t_70,g_se,x_16

 其中第一个RequestMappingHandlerMapping是标注@RequestMapping的方法信息以及其他handler方法。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Li65LuA5LmI6KaB5a2m57yW56iL,size_20,color_FFFFFF,t_70,g_se,x_16

(4) watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Li65LuA5LmI6KaB5a2m57yW56iL,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Li65LuA5LmI6KaB5a2m57yW56iL,size_20,color_FFFFFF,t_70,g_se,x_16 可以看到lookupPath是我们请求的路径

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Li65LuA5LmI6KaB5a2m57yW56iL,size_20,color_FFFFFF,t_70,g_se,x_16 我们点进这个方法watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Li65LuA5LmI6KaB5a2m57yW56iL,size_20,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Li65LuA5LmI6KaB5a2m57yW56iL,size_20,color_FFFFFF,t_70,g_se,x_16

只根据请求路径找 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Li65LuA5LmI6KaB5a2m57yW56iL,size_16,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Li65LuA5LmI6KaB5a2m57yW56iL,size_20,color_FFFFFF,t_70,g_se,x_16

 这个方法其实就是把directPathMatcher里真正符合条件的方法给matches  集合,如果这个matches集合中有两个及以上,就会抛出异常,也就是说在控制器中不能有两个相同的方法。最后返回HandlerMethod.类型的对象。

总结就是:

- SpringBoot自动配置欢迎页的 WelcomePageHandlerMapping 。访问 /能访问到index.html;
- SpringBoot自动配置了默认 的 RequestMappingHandlerMapping
- 请求进来,挨个尝试所有的HandlerMapping看是否有请求信息。

  - 如果有就找到这个请求对应的handler
  - 如果没有就是下一个 HandlerMapping

3. 前端控制器根据获得的mappedHandler,找到合适的适配处理器(HandlerAdapter),即创建对象。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 然后开始执行拦截器的preHandler方法。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 4.正式开始处理控制器方法。

提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)方法,处理请求。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:

a) HttpMessageConveter:将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息

b) 数据转换:对请求消息进行数据转换。如String转换成Integer、Double等

c) 数据格式化:对请求消息进行数据格式化。如将字符串转换成格式化数字或格式化日期等

d) 数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中

(1) Handler执行完成后,向DispatcherServlet 返回一个ModelAndview对象

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 

(2)接着执行return返回视图名称watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 (3)接着映射处理器调用posthandler方法,并且调用是反向的(具体见下图)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 跟进源码可知

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 5.  接着执行doDispatcher里的processDispatchResult方法

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 

 (1)进入此方法可知

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 

(2)然后紧接着渲染视图

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 (3)渲染视图完毕后执行拦截器的afterCompletion方法(调用也是逆向的),如下图源码分析

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 6.将视图渲染结果返回给客户端

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA54ix5aWz5Y-L55qE5bCP5p2O,size_20,color_FFFFFF,t_70,g_se,x_16

 

              这就是mvc执行过程的全部流程了,如有错误,敬请斧正。

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值