- 在DispatcherServlet处理请求过程分析中简单梳理了doDispatch的执行流程
- 获取Handler
- 获取Adapter
- 执行applyPreHandle
- 执行handle方法
- 执行applyPostHandle
- 处理返回结果
未解决问题
- 1、SpringMVC处理请求的时候如何找到相应Controller类和具体的方法呢?
- 可以猜测SpringMVC处理请求的时候如何找到相应Controller类和具体的方法的逻辑肯定和Handler、Adapter相关。
- 2、SpringMVC处理请求的时候是根据什么找到Controller类和具体的方法的呢?
- 可以大胆猜测是根据HTTP请求的请求协议信息内容匹配到的。
- 3、这些能够和请求协议关联上的内容放在哪的?什么时候放进去的?谁放进去的?
- 可以大胆猜测spring mvc 是spring 全家桶的一部分,Controller也是Bean,应该也会交给Spring在启动过程中统一处理这些问题。
问题关联
简单总结一下
- XmlWebApplicationContext.refresh()执行过程中,annotation-driven元素匹配的解析器AnnotationDrivenBeanDefinitionParser会注册RequestMappingHandlerMapping和RequestMappingHandlerAdapter的bean定义;
- RequestMappingHandlerMapping的懒加载对象实例化后,调用了afterPropertiesSet()方法,最终在afterPropertiesSet()方法执行完毕后将带有@RequestMapping注解的java类的相关信息设置到实例化之后的RequestMappingHandlerMapping对象中。也就是说相关请求对应的Controller类和方法的匹配条件在bean被加载完成后就已准备好。
- servlet执行init()逻辑时走到DispatcherServlet.initStrategies逻辑内部会把加载好的bean赋值给对应的属性
/** List of HandlerMappings used by this servlet */
private List<HandlerMapping> handlerMappings;
/** List of HandlerAdapters used by this servlet */
private List<HandlerAdapter> handlerAdapters;
/** List of HandlerExceptionResolvers used by this servlet */
private List<HandlerExceptionResolver> handlerExceptionResolvers;
- 所以结合DispatcherServlet处理请求的执行逻辑(doDispatch的执行流程),可以知道在获取Handle对象时确定了具体的Controller类和方法。
获取Handler(HandlerExecutionChain)
-
我们知道doDispatch的执行流程中会首先获取Handler,我们看下获取Handler的执行逻辑。
DispatcherServlet.getHandler.png - 循环比遍历已经初始化的handlerMappings,调用handlerMapping的getHandler方法。
- 根据request参数获取对应的HandlerMethod对象;
- 调用getHandlerExecutionChain方法。
- 判断参数handler是否匹配HandlerExecutionChain,如果是把参数handler赋值给HandlerExecutionChain对象chain,如果不是new HandlerExecutionChain(handler);
- 获取请求path,循环遍历adaptedInterceptors集合,添加匹配路径的拦截器到HandlerExecutionChain对象。
- 自此Handler对象(HandlerExecutionChain)被创建完成。
网友评论