springmvc工作原理源码解析

最近在研究springmvc的工作原理,看了源码顺手笔记下来,方便自己以后学习,在看源码前,先看下几个核心类:
1.HttpServletBean
主要做一些初始化的工作,将web.xml中配置的参数设置到Servlet中。比如servlet标签的子标签init-param标签中配置的参数。
2.FrameworkServlet
将Servlet与Spring容器上下文关联。其实也就是初始化FrameworkServlet的属性webApplicationContext,这个属性代表SpringMVC上下文,它有个父类上下文,既web.xml中配置的ContextLoaderListener监听器初始化的容器上下文。
3.DispatcherServlet
初始化各个功能的实现类。比如异常处理、视图处理、请求映射处理等。

我们主要从DispatcherServlet 的doDispatch方法研究。
当我们请求到达时,会被DispatcherServlet 拦截到,根据方法类型去下发请求,最后会走到doDispatch方法。

首先会到getHandler方法中获取HandlerExecutionChain的处理执行链在这里插入图片描述
点进getHandler方法后,可以看到最后会返回一个HandlerExecutionChain
在这里插入图片描述
其中handlerMappings是我们的处理器映射器,里面包含了5个,包括我们经常使用的RequestMappingHandlerMapping,这个方法会遍历所有的处理器映射器,然后依次执行处理器映射器的getHandler方法
在这里插入图片描述
然后会进入AbstractHandlerMapping类中的getHandler方法
在这里插入图片描述
这个方法第一行getHandlerInternal方法获取内部处理的handler,点进去

会执行到RequestMappingInfoHandlerMapping类中的getHandlerInternal方法
在这里插入图片描述
执行父类AbstractHandlerMethodMapping的getHandlerInternal方法,查找给定请求的处理程序方法。
在这里插入图片描述
然后会执行initLookupPath方法,初始化查找路径
在这里插入图片描述
会拿到我们请求的uri路径。执行lookupHandlerMethod方法得到处理该路径的方法。
在这里插入图片描述
getMappingsByDirectPath方法从mappingRegistry中获取到所有匹配的请求路径
在这里插入图片描述
addMatchingMappings方法会匹配真正适合的,比如get和post的请求路径一样,该方法会根据请求方式拿到合适的那个。
如果获取到多个,会进行判断,最终会执行bestMatch.getHandlerMethod()的方法,获取能处理当前请求的最终执行方法
在这里插入图片描述
会获取到执行请求的全路径名和方法名
在这里插入图片描述
getHandlerInternal方法最终会将请求包装成一个HandlerMethod返回,里面包含了bean的描述,beanFactory,方法,参数等信息。
在这里插入图片描述
然后在doDispatch方法中就会得到一个HandlerExecutionChain处理器执行链
在这里插入图片描述
根据得到的处理器通过getHandlerAdapter方法获取对应的处理器适配器
在这里插入图片描述
spring在启动时会初始化4个处理器适配器,依次遍历调用adapter.supports(handler)看是否能够处理我们的请求,如果为true就直接返回适配器
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
真正执行我们的程序方法是在ha.handle这个方法中调用的
在这里插入图片描述
在这里插入图片描述
会执行RequestMappingHandlerAdapter的handleInternal方法,然后会调用invokeHandlerMethod方法
在这里插入图片描述
在这个方法中我们可以看到setHandlerMethodArgumentResolvers和setHandlerMethodReturnValueHandlers两个方法,他们分别是设置参数解析器和结果解析器
在这里插入图片描述
其中参数解析器有27个,就是我们平时在方法参数上添加的一些参数注解,这里会设置进去,请求到达的时候依次执行这些参数解析器进行比对
在这里插入图片描述
结果解析器有15个,返回的时候会依次执行这些解析器,匹配我们的返回结果,比如我们标注了@ResponseBody注解最终就会由RequestResponseBodyMethodProcessor处理
在这里插入图片描述
执行invocableMethod.invokeAndHandle方法
在这里插入图片描述
在这里插入图片描述
会调用InvocableHandlerMethod类中的invokeForRequest方法,该方法会调用getMethodArgumentValues方法来获取真正的参数解析器
在这里插入图片描述
在这里插入图片描述
获取方法的参数,遍历参数的个数,调用resolvers.supportsParameter,看那个参数解析器能支持此参数的解析
在这里插入图片描述
这边会获得所有的参数解析器,遍历执行,最终得到可以处理该参数的参数解析器,房后放入缓存argumentResolverCache中,方便下次调用
在这里插入图片描述
resolvers.resolveArgument方法解析参数的值并填充参数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
依次填充每个参数,完成后会返回一个参数的数组,此时已经将参数绑定了
在这里插入图片描述
绑定完参数后会调用this.doInvoke(args)方法
在这里插入图片描述
该方法最终会调用method.invoke(this.getBean(), args)方法通过反射执行我们真正在Controller层写的目标方法
在这里插入图片描述
拿到我们目标方法的返回值后会调用returnValueHandlers.handleReturnValue来处理我们的返回值,就是刚才说的15个结果解析器
在这里插入图片描述
调用selectHandler方法查询合适的处理器
在这里插入图片描述
遍历所有的结果处理器,调用handler.supportsReturnType(returnType)看每个处理器是否支持当前的结果处理,最终会返回一个HandlerMethodReturnValueHandler处理器
在这里插入图片描述
在这里插入图片描述
调用handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest)方法将数据协会浏览器,此时我们就可以在浏览器看到我们的接口结果了
在这里插入图片描述
整体流程大致就是这样,文档是我自己按照源码一步一步走下来的,感兴趣的朋友也可以自己按照文档走一遍,有问题可以在下方留言。
原创不易,谢谢大家。
多多点赞~~~~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值