SpringMVC执行流程解析(PS:使用了适配器模式)
1、源码解析说明
SpringMVC 中的 HandlerAdapter, 就使用了适配器模式;
下面我们通过源码来分析SpringMVC 中的 HandlerAdapter是如何使用适配器模式的:
//前端控制器DispatcherServlet类 public class DispatcherServlet extends FrameworkServlet { //DispatcherServlet类中的核心方法doDispatch protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request;//将request交给HttpServletRequest HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; …………(省略部分代码) //通过request可以得到请求对应的控制器,即controller/handler mappedHandler = getHandler(processedRequest); …………(省略部分代码) //根据handler得到对应的适配器 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); …………(省略部分代码) //通过适配器去调用对应controller的方法,并返回ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); }
适配器接口HandlerAdapter的源码:
public interface HandlerAdapter { boolean supports(Object handler); @Nullable ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; long getLastModified(HttpServletRequest request, Object handler); }
适配器接口HandlerAdapter的具体实现类,即具体的适配器类
列出其中一个具体的实现类HttpRequestHandlerAdapter的源码,可以看到无非就是重写了接口中的三个方法,
其中supports方法就是判断handler是否对应这个适配器实现类,返回一个布尔值;
而handle方法就是去调用具体的controller方法,并返回ModelAndView
public class HttpRequestHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { return (handler instanceof HttpRequestHandler); } @Override @Nullable public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((HttpRequestHandler) handler).handleRequest(request, response); return null; } @Override public long getLastModified(HttpServletRequest request, Object handler) { if (handler instanceof LastModified) { return ((LastModified) handler).getLastModified(request); } return -1L; } }
对以上源码进行总结,SpringMVC 中的 HandlerAdapter用到适配器模式的流程:
- 将request交给HttpServletRequest
- 通过request可以得到请求对应的控制器,或者叫处理器;即controller/handler
- 根据handler得到对应的适配器
- 通过适配器去调用对应controller的方法,并返回ModelAndView(表明看执行的是适配器的handle方法,实际上适配器执行的就是对应controller的方法)
有了适配器模式,最终是通过具体的适配器类来调用controller中的方法,那么为什么不直接去调用controller中的方法,而要通过适配器来调用呢,这不是多此一举吗?
当然不是多此一举,可以看到处理器的类型不同,有多重实现方式,那么调用方式就不是确定的,如果需要直接调用 Controller 方法,需要调用的时候就得不断是使用 if else 来进行判断是哪一种子类然后执行。那么如果后面要扩展 Controller,就得修改原来的代码,这样违背了 OCP 原则。
另外,把每个controller的方法差异封装到各个 HandlerAdapter的实现类里,对外只暴露统一的handle方法。
前面在类适配器模式我们提到,由于适配器类继承了被适配器类的方法,因此在适配器类中我们可以会直接调用被适配器类的方法,这样就使得被适配器类的方法在 Adapter 中会暴露出来,增加了使用的成本;而SpringMVC中的HandlerAdapte使用了适配器模式后就解决了这个问题。
2、springmvc处理请求流程简要说明
流程图:
具体步骤:
- 用户发送请求至前端控制器DispatcherServlet;
- DispatcherServlet收到请求调用HandlerMapping处理器映射器;
- 处理器映射器根据请求url找到具体的处理器Handle,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispathcerServlet;
- DispatcherServlet根据返回的Handle找到对应的处理器适配器HandlerAdapter,通过处理器适配器调用处理器;
- 执行处理器(Controller,也叫后端控制器);
- Controller执行完成后返回ModelAndView;
- HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet;
- DispatcherServlet将ModelAndView传给ViewResolver视图解析器;
- ViewResolver解析后返回具体View对象;
- DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中),或者说视图渲染是将模型数据在ModelAndView对象中填充到request域);
- DispathcerServlet响应用户。
摘自:https://blog.csdn.net/can_chen/article/details/105524137