我们都知道SpringMVC的核心就是DispatcherServlet,它负责接收请求和调度,在开始原码解析前先来看看SpringMVC请求的一个处理流程图:
1)客户端发送请求,DispatcherServlet接收请求
2)DispatcherServlet将请求交给DefaultAnnotationHandlerMapping找到对应的映射方法
3)通过对应的DefaultAnnotationHandlerAdapter invoke特定的方法
4)调用自己的Controller和相应的方法,给Model设置数据和返回视图
5)DefaultAnnotationHandlerAdapter组装ModelAndView并返回给DispatcherServlet
6)通过InternalResourceViewResolver解析
7)响应客户端
对请求流程有了一个初步的了解后,接下来我们开始原码分析:
确定请求入口:
因为DispatcherServlet本质上是一个Servlet所有它一定有doPost()和doGet()方法,而DispatcherServlet又继承FrameworkServlet,通过分析我们在FrameworkServlet中找到请求处理方法,如图:
而doPost()和doGet()方法又会调用pocessRequest()这个方法,如图:
因此我们在processRequest这个方法上打上断点。
接下来开启debug并发送请求,来到断点处processRequest方法,其原码如下:
//处理请求
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
long startTime = System.currentTimeMillis();
Throwable failureCause = null;
//获取LocaleContextHolder中原来保存的LocaleContext
//刚开始一般是null
LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
//获取当前请求的LocaleContext
LocaleContext localeContext = buildLocaleContext(request);
//获取原有的属性
RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
//获取当前请求的属性
ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);
//异步操作
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());
//将当前请求的LocaleContext和ServletRequestAttributes设