springmvc 执行流程源码分析
// 前端控制器 springmvc最核心的类
public class DispatcherServlet extends FrameworkServlet {
// 这个方法负责处理请求,一次请求, 调用一次Dispatcher方法
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 通过请求路径获取对应要执行的处理器
// 实际上返回的处理器执行链对象 (所有的处理器和拦截器对象)
HandlerExecutionChain mappedHandler = getHandler(request);
// 根据处理器获取处理器适配器对象
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // handler就是controller
// 执行该请求对应的所有拦截器中的 preHandle 方法
if (!mappedHandler.applyPreHandle(request, response)) {
return;
}
// 调用处理器方法 返回modelAndView对象
// 在这里进行的数据绑定,实际上调用处理器方法之前要给处理器方法传参
// 需要传参的话, 这个参数要经过一个复杂的数据绑定过程(将前端提交的表单转换成 pojo 对象)
mv = ha.handle(request, response, mappedHandler.getHandler());
// 执行该请求对应的所有拦截器中的 postHandle 方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
// 处理分发结果(本质上就是响应浏览器)
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
}
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception {
// 渲染操作
render(mv, request, response);
// 执行该请求中的所对应的所有拦截器的 afterCompletion 方法
mappedHandler.triggerAfterCompletion(request, response, (Exception)null);
}
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
// 通过视图解析器解析, 返回视图view对象
View view = this.resolveViewName(viewName, mv.getModelInternal(), locale, request);
// 调用视图对象的渲染方法(完成响应)
view.render(mv.getModelInternal(), request, response);
}
protected View resolveViewName(String viewName, @Nullable Map<String, Object> model, Locale locale, HttpServletRequest request) throws Exception {
// 视图解析器
ViewResolver viewResolver;
// 通过视图解析器解析返回视图对象 View
View view = viewResolver.resolveViewName(viewName, locale);
}
}
// 视图解析器接口
public interface ViewResolver {
View resolveViewName(String viewName, Locale locale) throws Exception;
}
// 视图接口
public interface View {
void render(@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
}
// 每一个接口都有接口下的实现类, 例如view接口实现类:ThymeleafView InternalResourceView
根据请求获取处理器执行链
WARNING
springmvc 执行的第一步:
通过处理器映射器找到请求路径对应的处理器方法 .
分析这一行代码:
HandlerExecutionChain mappedHandler = getHandler(request);
- HandlerExecutionChain - 处理器执行链对象
- HandlerExecutionChain 中的属性
public class HandlerExecutionChain {
// 底层对应的是一个 handlerMethod 对象
private final Object handler; // MethodHandler
// 该请求对应的所有拦截器按照顺序放到了ArrayList集合中
// 所有的拦截器对象是在服务器启动时创建好的 .
private final List<HandlerInterceptor> interceptorList;
}
handlerMethod 是什么 ?
handlerMethod 是最核心的要执行的目标, 翻译为: 处理器方法.
注意:HandlerMethod 是在服务器启动时初始化 spring 容器的时候, 就已经创建好了.
这个类当中的重要的属性包括: beanName 和 method
例如下代码:js@Controller pulic class UserController() { @RequestMapping("/login") public String login(User user) { return ... } }
那么以上代码对应了一个 HanlderMethod 对象
jspublic class HanlderMethod { private String beanName = "userController"; private Method loginMethod; }
getHandler(request);
// 这个方法还是在 DispatcherServlet 类中
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
Iterator var2 = this.handlerMappings.iterator();
while(var2.hasNext()) {
HandlerMapping mapping = (HandlerMapping)var2.next();
// 通过合适的 HandlerMapping 才能获取到 HandlerExecutionChain 对象
// 如果你处理器中使用了 @RequestMapping 注解, 那么以下代码中的mapping是: requestMappingHandlerMapping
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
重点:
处理第一步调用的是 :HandlerExecutionChain mappedHandler = getHandler(request)
其本质上调用的是: HandlerExecutionChain handler = mapping.getHandler(request);
HandlerMapping 是接口:
是处理器映射器, 专门负责映射的, 就是根据请求路径映射处理器方法的.
HandlerMapping 接口下有很多实现类:
例如有名的且常用的: RequestMappingHandlerMapping
这个 RequestMappingHandlerMapping 叫做: @RequestMapping 专用处理器映射器对象
如果不使用这个注解,就要进行 xml 文件进行配置, 就会使用其他的映射器处理器实现类
HandlerMapping 对象 是在服务器启动阶段进行创建的, 所有的 HandlerMapping 对象都是在服务器启动创建,并且存放在集合中.
public class DispatcherServlet {
private List<HandlerMapping> handlerMappings;
}
requestMappingHandlerMapping 中的 getHandler(request) HandlerExecutionChain handler = mapping.getHandler(request);
mapping.getHandler(request) 方法一定是获取了 HandlerMethod 将其赋值给 HandlerExecutionChain 中的 handler 属性.
jspublic class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping { public void registerMapping(RequestMappingInfo mapping, Object handler, Method method) { super.registerMapping(mapping, handler, method); this.updateConsumesCondition(mapping, method); } } public class AbstractHandlerMethodMapping { public void registerMapping(T mapping, Object handler, Method method) { this.mappingRegistry.register(mapping, handler, method); } public void register(T mapping, Object handler, Method method) { HandlerMethod handlerMethod = createHandlerMethod(handler, method); } protected HandlerMethod createHandlerMethod(Object handler, Method method) { if (handler instanceof String beanName) { // 服务器启动时执行 return new HandlerMethod(beanName, this.obtainApplicationContext().getAutowireCapableBeanFactory(), this.obtainApplicationContext(), method); } else { return new HandlerMethod(handler, method); } } }
这一步牵连到的类:
- HandlerExecutionChain 处理器执行链
- HanlderMethod - 处理器方法
- HandlerInterceptor - list 中的拦截器
- HandlerMapping
- requestMappingHandlerMapping (HandlerMapping 接口的实现)
DispatcherServlet 流程概述
用户发起请求, DispatcherServlet(前端控制器) 拦截到请求, 通过处理器映射器(handlerMapping),返回一个 handler 处理器(实质是一个 handlerExecutionChain), 根据返回的 handler, 来获取适合的 handlerAdapter 处理器适配器,下面进行 preHandler, 根据 handlerAdapter 来调用处理器方法(参数处理,绑定), 返回逻辑视图名称给到 处理器适配器, 然后处理器适配器根据逻辑视图名称, 返回 MV(modelAndView),给到前端控制器, 前端控制利用视图解析器 ViewResolver, 解析出视图对象 View, 返回给前端控制器, 接下来根据 View 视图解析对象,进行渲染,
服务器启动
- 初始化 spring 上下文, 也就是创建所有的 Bean, 让 IOC 容器将其管理起来
- 初始化 springMVC 相关的对象: 处理器映射器, 处理器适配器 等