Spring MVC_运行原理
重要组件
1、HandlerMapping
代表请求地址到 handler 之间的映射。
2、HandlerExecutionChain
handler 的执行链对象,由 handler 对象和所有 handler 拦截器组成。SpringMVC 调用 HandlerMapping 接口中定义的 getHandler()方法获取该对象。
3、HandlerAdapter
执行请求参数注入、类型转换、数据验证等具体操作。
关键节点
1、获取 HandlerExecutionChain 对象
所在 API:org.springframework.web.servlet.DispatcherServlet
源码位置:1101 行、916 行 Tips:如果当前请求没有经过映射,那么 mappedHandler 是否为 null 呢?
- 如果配置了 mvc:default-servlet-handler 则不为 null
- 如果没有配置 mvc:default-servlet-handler 则为 null
2、获取 HandlerAdapter 对象
所在 API:org.springframework.web.servlet.DispatcherServlet
源码位置:923 行
3、调用拦截器的 preHandle()方法
所在 API:org.springframework.web.servlet.DispatcherServlet
源码位置:939 行
4、为模型对象注入请求参数
所在 API:org.springframework.web.bind.annotation.support.HandlerMethodInvoker
源码位置:170 行、373 行
5、调用目标 handler 方法
所在 API:org.springframework.web.servlet.DispatcherServlet
源码位置:945 行
6、调用拦截器的 postHandle()方法
所在 API:org.springframework.web.servlet.DispatcherServlet
源码位置:954 行
7、处理视图转发相关
所在 API:org.springframework.web.servlet.DispatcherServlet
源码位置:959 行
8、处理异常
所在 API:org.springframework.web.servlet.DispatcherServlet
源码位置:998 行
9、渲染视图
所在 API:org.springframework.web.servlet.DispatcherServlet
源码位置:1012 行
① 解析视图名称,将逻辑视图转换为物理视图
所在 API:org.springframework.web.servlet.DispatcherServlet
源码位置:1204 行、1266 行
② 渲染视图
所在 API:org.springframework.web.servlet.DispatcherServlet
源码位置:1225 行
③ 将模型数据暴露到请求域
所在 API:org.springframework.web.servlet.view.AbstractView
源码位置:266 行
④ 将模型数据保存到请求域
所在 API:org.springframework.web.servlet.view.AbstractView
源码位置:374 行
⑤ 转发
所在 API:org.springframework.web.servlet.view.InternalResourceView
源码位置:209 行
10、调用拦截器的 afterCompletion 方法
所在 API:org.springframework.web.servlet.DispatcherServlet
源码位置:1030 行
annotation 相关
我们在前面的操作中发现,使用了mvc:default-servlet-handler
和mvc:view-controller
后必须使用mvc:annotation-driven
关键原因是他们加载使用的HandlerMapping不同。
1、三个都没有使用时有效的 HandlerMapping
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
其中DefaultAnnotationHandlerMapping
负责把所有 handler 类中的 handler 方法收集起来。
2、增加了 mvc:default-servlet-handler 或 mvc:view-controller 后有效的 HandlerMapping
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
很明显,DefaultAnnotationHandlerMapping
没了,而SimpleUrlHandlerMapping
只能映射静态资源。
所以我们通过@RequestMapping 映射的 handler 方法无效了。
3、增加了 mvc:annotation-driven 后
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
加入了mvc:annotation-driven
后最关键的是增加了RequestMappingHandlerMapping
,从而可以映射我们的 handler 方法。