# SpringMVC执行流程
/*
springMVC的核心处理类DispatcherServlet间接继承了HttpServlet,要处理请求响应必须将
DispatcherServlet和映射路径注册到tomcat容器中,tomcat接收前端HTTP请求后,到容器中找到
DispatcherServlet,然后将HTTP数据封装为request和response并交给DispatcherServlet处理。
*/
/*以下是对DispatcherServlet核心方法的分析,源代码做了略微删减,保留了主要部分*/
protected void doDispatch(request,response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
try {
try {
ModelAndView mv = null;
Object dispatchException = null;
try {
// 1.文件上传解析器检查是否是文件上传请求,并将请求封装为文件上传请求
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
// 2.处理器映射器找到目标处理器和拦截器生成HandlerExecutionChain(执行链路)
mappedHandler = this.getHandler(processedRequest);
// 3.在HandlerAdapter中根据HandlerExecutionChain匹配合适的适配器并返回
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
// 4.(如果存在)执行拦截器的preHandle返回false 则return;并倒序执行所有拦截器的afterCompletion。
// 返回true则交给适配器处理。
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
/* 5.将请求响应和目标处理器交给适配器处理:
适配器会先去获取Handler的接收和返回参数类型,根据获取到的参数类型匹配对应的参数解析器和返回值处理器,
参数解析器利用数据绑定器(WebDataBlnder)先用数据转换器(Converters)将HTTP文本数据转换为java数据类型 ,
然后将数据绑定到对应形参中(利用反射),最后执行目标Handler,执行完后调用之前获取的返回值处理器。
返回值处理器:
会先去先匹配对应的内容协商策略,内容协商策略会根据浏览器能接收的数据类型和返回值处理器能返回的数据类型
匹配所有能用的消息转换器,然后获得其中最佳匹配媒体类型将数据转为(JSON,String等)并返回。
如果是json类型的返回值处理器则会直接响应数据到前端并且返回null,
如果是string或其他类型的返回值处理器则会返回ModelAndView,由视图解析器来处理ModelAndView,
所以适配器执行完目标处理器会返回ModelAndView或者null;
*/
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 6.判断如果mv不等于null并且没有view,则设置view为默认view
this.applyDefaultViewName(processedRequest, mv);
// 7.适配器处理完后会倒序执行所有拦截器的PostHandle方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception var20) {
// 8..以上所有操作若是抛出异常则保存异常信息。
dispatchException = var20;
} catch (Throwable var21) {
dispatchException = new NestedServletException("Handler dispatch failed", var21);
}
/* 9.doDispatcher方法最终调用processDispatchResult来处理异常信息、处理ModelAndView进行页面渲染
或者直接响应数据。
异常处理: 判断是否存在异常信息,存在则寻找能处理本次异常的异常处理器,找不到则重新发起/error请求,交给errorHandler处理。
页面渲染: 基于内容协商策略在多个视图解析器中获得最佳匹配的视图解析器,然后判断返回值字符串存在redirect或forward就
基于原生Servlet的转发或重定向完成处理,最终将数据响应到前端,若返回值是普通字符串则利用ThymeleafView视图解析,
最后渲染视图到前端。
*/
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
} catch (Exception var22) {
} catch (Throwable var23) {
} finally{} // 区分下面finally的占位行
}finally{
// 10.finally最后会执行 拦截器的afterCompletion方法
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
}
SpringMVC执行流程核心源码分析
于 2022-10-24 16:20:49 首次发布