SpringMVC源码分析_2 DispatcherServlet处理请求原理
2 DispatcherServlet处理请求原理
作者:田超凡
版权所有,严禁复制转载
1 DispatcherServlet和Servlet的关系
- DispatcherServlet是SpringMVC的神经中枢,DispatcherServlet是SpringMVC核心处理请求控制器,是整个Web层框架最为核心的请求处理器,负责接收请求后经过一系列映射转换、参数解析校验和绑定、处理器解析、处理器适配、拦截机制,调度并处理请求,最后将响应结果解析并绑定到视图渲染后返回响应给客户端
- DispatcherServlet本质是一个Servlet,它的继承关系链如下:
DispatcherServlet
- FrameworkServlet
- HttpServlet
- GenericServlet
- Servlet
- DispatcherServlet在基于Spring5.x / SpringBoot基于无注解驱动集成在SpringMVC中,需要在Web容器初始化时创建并注册到SpringMVC上下文(AnnotationConfigWebApplicationContext)中,在注册时需要配置拦截规则,默认拦截所有请求,并设置启动优先级为最高级别
public class DispatcherServletInitializer implements WebApplicationInitializer
{
// TODO TCF 初始化SpringMVC上下文
AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext();
// TODO TCF 注册SpringMVC核心配置类
annotationConfigWebApplicationContext.register(SpringMVCConfig.class);
// TODO TCF 创建DispatcherServlet
ServletRegistration dynamic = servletContext.addServlet(“dispatcherServlet”,new DispatcherServlet(annotationConfigWebApplicationContext));
// TODO TCF DispatcherServlet默认拦截所有请求
dynamic.addMapping(“/”);
// TODO TCF 设置DispatcherServlet最优先加载的Servlet
// TODO TCF 在使用了多个Servlet处理请求的情况下,可以保证DispatcherServlet的优先级为最高
dynamic.setLoadOnStartup(1);
// TODO TCF 开启ServletContext异步处理请求的支持,等效于@EnableAsync
dynamic.setAsyncSupported(true);
}
2 DispatcherServlet处理请求原理图
3 DispatcherServlet处理请求原理
- 客户端发送的请求被DispatcherServlet拦截
- 根据OOP多态里氏替换原则,对于子类重写父类的方法时,会优先调用父类的方法执行,再调用子类的方法执行,因此DispatcherServlet处理请求的方法调用顺序是:
GenericServlet service()
- HttpServlet service()
- 根据请求方式调用doGet() / doPost()
- FrameworkServlet doGet() / doPost()
- FrameworkServlet processRequest()
- FrameworkServlet doService()
- DispatcherServlet doService()
- DispatcherServlet doDispatch()
综上所述,DispatcherServlet处理请求的核心实现是在doDispatch()中
- DispatcherServlet开始处理请求,执行doDispatch()方法
- getHandler()解析HandlerMapping,获取HandlerExecutionChain(封装了HandlerMethod处理请求的方法和HandlerInterceptor拦截器)
AbstractHandlerMapping getHandler()
- AbstractHandlerMethodMapping getHandlerInternal()
- HandlerMethod
- HandlerInterceptor
- HandlerExecutionChain
- getHandlerAdapter()获取HandlerAdapter处理器适配器,用于执行处理器方法HandlerMethod
AbstractHandlerMappingAdapter supports()
在所有已经注册的HandlerAdapter中获取能够适配当前处理方法HandlerMethod的 HandlerAdapter
- applyPreHandlers() 调用HandlerInterceptor作用链中每个拦截器的前置拦截方法preHandler(),拒绝访问或者执行目标方法HandlerMethod过程中如果抛出异常,会调用每个拦截器的afterCompletion()实现最终拦截
- AbstractHandlerMethodAdapter handler() 执行目标处理请求的方法HandlerMethod,返回ModelAndView
RequestMappingHandlerAdapter handlerInternal()
- invokeHandlerMethod()
- ServletInvocableHandlerMethod invokeAndHandler()
- InvocableHandlerMethod invokeForRequest()
- InvocableHandlerMethod getMethodArguments()
- InvocableHandlerMethod doInvoke()
- HandlerMethodReturnValueHandlerComposite handlerReturnValue()
- 根据HandlerMethod的执行返回结果,封装ModelAndViewContainer
ViewNameMethodReturnValueHandler / ViewMethodReturnValueHandler
handlerReturnValue()
- RequestMappingHandlerAdapter getModelAndView()
- ModelAndView
- applyPostHandlers() 调用HandlerInterceptor作用链中每个拦截器的postHandler()实现后置增强拦截
- processDispatcherServlet() 调用AbstractView render()进行视图渲染,
调用triggerAfterCompletions()调用HandlerInterceptor作用链中每个拦截器的afterCompletion()实现最终增强拦截处理
4 DispatcherServlet处理请求源码分析
- 客户端请求被DispatcherServlet拦截
GenericServlet -> service()
HttpServlet -> service()
HttpServlet -> doGet() / doPost() 根据请求方式不同,调用doGet() / doPost()方法
FrameworkServlet -> doGet() / doPost()
FrameworkServlet -> processRequest()
FrameworkServlet -> doService()
DispatcherServlet -> doService()
DispatcherServlet -> doDispatch()
- getHandler 获取匹配当前请求URL的HandlerMapping,获取HandlerMethod、HandlerInterceptor,将处理请求的方法(HandlerMethod)和拦截器(HandlerInterceptor)封装到HandlerExecutionChain并返回,调用链如下:
AbstractHandlerMapping getHandler()
- AbstractHandlerMethodMapping getHandlerInternal()
- lookupForHandlerMethod()
- HandlerMethod
- getHandlerExecutionChain()
- HandlerExecutionChain
解析HandlerInterceptor拦截器,将匹配目标HandlerMethod的所有HandlerInterceptor拦截器和HandlerMethod组装在一起,封装为HandlerExecutionChain返回
调用AbstractHandlerMapping getHandler()获取处理请求的方法HandlerMethod
- AbstractHandlerMethodMapping getHandlerInternal()
- AbstractHandlerMethodMapping lookupForHandlerMethod()
获取处理请求的方法HandlerMethod
- getHandlerExecutionChain() 组装匹配当前HandlerMethod的HandlerInterceptor拦截器,将HandlerInterceptor拦截器作用链和HandlerMethod封装成HandlerExecutionChain返回
lookupHandlerMethod根据请求URL匹配处理请求的方法HandlerMethod
getHandlerAdapter 获取调用HandlerMethod的适配器HandlerAdapter
AbstractHandlerMethodAdapter supports() 校验当前适配器是否能够适配处理请求的目标方法HandlerMethod
- HandlerExecutionChain applyPreHandler() 调用HandlerInterceptor拦截器作用链中每个拦截器的preHandler()前置拦截,对于拒绝访问或者HandlerMethod执行出现异常会再调用每个拦截器的afterCompletion()实现最终增强拦截
- AbstractHandlerMethodAdapter handler()执行处理请求的方法HandlerMethod,返回ModelAndView,调用处理请求方法HandlerMethod的调用链如下:
AbstractHandlerMethodAdapter handler()
- RequestMappingHandlerAdapter handlerInternal()
- RequestMappingHandlerAdapter invokeHandlerMethod()
- ServletInvocableHandlerMethod invokeAndHandler()
- InvocableHandlerMethod invokeForRequest()
- InvocableHandlerMethod getMethodArguments()
- HandlerMethodArgumentResolverComposite resolveArguments()
- HandlerMethodArgumentResolverComposite getArgumentResolver()
- HandlerMethodArgumentResolver resolveArgument()
- InvocableHandlerMethod doInvoke()
- HandlerMethodReturnValueHandlerComposite handleReturnValue()
- ViewNameMethodReturnValueHandler / ViewMethodReturnValueHandler handlerReturnValue() 根据处理请求方法返回结果使用不同的返回值处理器解析视图名称,绑定到ModelAndViewContainer中,用于后续创建ModelAndView
- RequestMappingHandlerAdapter getModelAndView()
- ModelAndView
- applyPostHandlers() 调用HandlerInterceptor作用链中每个拦截器的postHandler()实现后置增强拦截
- processDispatcherServlet() 调用AbstractView render()实现视图解析和渲染,最终调用triggerAfterCompletion(),调用HandlerInterceptor作用链中每个拦截器的afterCompletion()实现最终增强拦截,返回视图响应给客户端
至此,DispatcherServlet处理请求流程结束