DispatcherServlet 服务过程
springMVC调用组件处理请求的整个过程
-
从Servlet接口的public void service(ServletRequest req, ServletResponse res)方法开始看
-
在HttpServlet中重写了service(ServletRequest req, ServletResponse res)并且调用了重载的service(HttpServletRequest req, HttpServletResponse resp),在这个重载的方法中获得请求的方法(req.getMethod();),去调用对应的方法(doGet(req, resp);等等)
此处用哈夫曼树思想,最常见就是get,放前面,后面就越来越少用,程序优化点滴做起 -
接下来FrameworkServlet中重写了service(HttpServletRequest request, HttpServletResponse response)
也就是说frameworkServlet其实就算对请求方式patch和为null作出了特殊处理processRequest():如果不是patch和为null调 super.service(request, response); 也就是去执行对应的doXXX
-
最后发现 常见的4个请求方式在doXXX里又调了processRequest
那么直接关注FrameworkServlet的processRequest方法就行了
-
在processRequest 中调了doService,doService在DispatcherServlet中得到了实现,在里面一堆代码里执行了doDispatch(request, response);
然后我们分析一下doDispatch:
下面的分析都按代码执行顺序介绍
- 先处理了 HandlerExecutionChain mappedHandler(处理程序执行链)
它里面第一个是匹配的控制器方法,第二个是拦截器 第三个是使用后的拦截器索引
-
然后是HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
处理器适配器
这里是获得对象没有调用方法,真正调用方法是在ha.handle (1061 行
这里获得的其实就是那个控制器对象,具体调用还得看下面那个方法,相当于这里反射已经获得了对象,准备调用控制器方法
-
接下来执行拦截器的postHandle:
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
-
调用控制器方法的:
在里面进行了形参的赋值 请求报文,cookie信息,session信息,数据转型(例如:String类型的转Integer,获取数组)等等都在这里处理的
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
- 调用拦截器PostHandle
mappedHandler.applyPostHandle(processedRequest, response, mv);
- 后续的处理 处理ModelAndView:
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
processDispatchResult里面的:
1.如果发生错误后的处理
2.渲染视图的:
比如 模型数据放在请求域,根据视图名称创建对应的视图
render(mv, request, response);
3.最后 调用拦截器里的AfterCompletion方法
mappedHandler.triggerAfterCompletion(request, response, null);