先看一下springMVC的流程图
1、 springMvc的主要构成是
1.1、前端控制器(dispatcherServlet)
1.2、请求到处理器映射(handlerMapping)
1.3、处理器适配器(HandlerAdapter)
1.4、视图解析器(ViewResolver)
2、springMvc处理请求的流程如下
2.1、用户发送请求至前端控制器DispatcherServlet;
2.2、DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
2.3、处理器映射器根据请求url找到具体的处理器
2.4、DispatcherServlet 调用 HandlerAdapter处理器适配器
2.5、HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器)
2.6、Handler执行完成返回ModelAndView;
2.7、HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
2.8、DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
2.9、ViewResolver解析后返回具体View;
2.10、DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
2.11、DispatcherServlet响应用户。
今天我们主要分析一下2.3-2.6
首先根据前端发送请求的request对象的到具体的处理器,方法的入口在DispatcherServlet中的1043行
org.springframework.web.servlet.DispatcherServlet#doDispatch
而具体的处理方式是将handler转换为HandlerExecutionChain
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
接下来会根据HandlerMethod获取对应的HandlerAdapter,该方法使用的是适配器模式,
public interface HandlerAdapter {
// 用于判断当前HandlerAdapter是否能够处理当前请求
boolean supports(Object handler);
// 如果当前HandlerAdapter能够用于适配当前请求,那么就会处理当前请求中
// 诸如参数和返回值等信息,以便能够直接委托给具体的Handler处理
@Nullable
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
@Deprecated
long getLastModified(HttpServletRequest request, Object handler);
}
handlerAdapter接口总共有四个实现类,分别对应处理不同的“controller”;
HandlerMapping
的作用主要是根据request请求获取能够处理当前request的handler,而HandlerAdapter
的作用在于将request中的各个属性,如request param适配为handler能够处理的形式 。
关于HandlerAdapter.supports()方法,有这个方法的主要原因是,HandlerMapping是可以有多种实现的,Spring会遍历这些具体的实现类,判断哪一个能够根据当前request产生一个handler,因而对于HandlerAdapter而言,其是不知道当前获取到的handler具体是什么形式的,不同的HandlerMapping产生的handler形式是不一样的,比如RequestMappingHandlerMapping产生的handler则是封装在HandlerMethod对象中的,因而这里HandlerAdapter需要一个方法能够快速过滤掉当前产生的handler是否为其能够进行适配的,这个方法就是HandlerAdapter.supports()方法。如下是该方法的实现。比如@Controller注解使用的是RequestMappingHandlerAdapter进行处理的。
在handlerAdapter内部会封装请求参数,如果使用的是@RequestBody会根据请求的参数反射设置参数。
最后在spring容器中获取到对应的bean后进行反射调用业务的controller对应的处理方法。
org.springframework.web.method.support.InvocableHandlerMethod#doInvoke
后期会补充一下 HandlerAdapter另外几种处理方式。