当初学习Spring MVC时,最吸引我的是它如何降低整个程序各块组件之间的耦合度,以及各组件之间的通信流程。降低耦合度的优点无疑就是方便了以后对代码进行扩展,维护,让各个组件独立开来,又能清晰地互相协调通信,是给我感受最深的Spring MVC的优点。使用Spring MVC的Web项目,当用户发送一个HTTP请求后,数据经过哪些处理,如何处理以及如何显示到view上,下面就来看一下简单的配置项目,看看它有哪些组件,以及如何一步一步进行各组件之间的协同工作的。
Spring MVC工作流
先来看看Spring MVC收到一个HTTP请求后的工作流程,看看它都用到了哪些API,当你搞懂了整个工作流程后,才能明白各组件之间的关系!
由上面的流程图可以看到,对于一个用户发送的url请求:
- 该请求首先会由前端控制器DispatchServlet(或者说是分发器Servlet)接收。
- 前端控制器会对处理器映射器HandlerMapping发送请求,在处理器映射器中查找可以处理该请求的Handler。处理器映射器的作用就是根据url路径,去查找相应的处理器Handler。
- 前端控制器得到处理器映射器返回的执行链后,再去请求处理器适配器HandlerAdapter,根据执行链去执行相应的Handler。
- 处理器Handler执行完成后,向处理器适配器返回一个ModelAndView对象,里面封装了数据模型和视图信息。处理器适配器接收到ModelAndView对象后,再把它返回给前端控制器。
- 前端控制器收到ModelAndView对象后,去请求视图解析器View resolver,视图解析器的作用是将ModelAndView对象中的View信息(View是一个接口,它可以有不同的实现,如jsp、excel,pdf等),解析得到一个View页面,例如把View里面的JSP路径信息解析返回一个JSP页面。最后把View页面返回给前端控制器。
- 最后,前端控制器将具体视图View进行渲染,把Model里面的数据填充到View页面中,得到最终要返回给用户看的视图。
- 前端控制器向用户发送回应请求。
上面就是Spring MVC在接收到用户发送的请求后,处理的过程,可以看到,里面使用到的组件有前端控制器、处理器映射器、处理器适配器、处理器与控制器,视图解析器和视图。下面来总结一下这些组件以及一些定义的接口。
组件及接口
前端控制器DispatcherServlet
第一个,也是十分重要的一个,前端控制器DispatcherServlet,它是一个实现类,作用可以说是一个转发器,负责对各个组件进行统一调度。由上面的工作流程可以看到,DispatcherServlet接收用户HTTP请求,根据在处理器映射器中找到的Handler,到处理器适配器中执行,处理器Handler进行完业务逻辑处理后,返回一个ModelAndView对象,里面包含了Model数据模型和View视图信息。最后DispatcherServlet请求视图解析器View solver解析得到真正的视图,并把视图渲染,填入数据域,最终返回给用户。
可以看到,前端控制器DisparcherServlet能找到各个组件,进行统一通信,管理,降低了各组件之间的耦合度。
处理器映射器HandlerMapping
就像MyBatis里的SQL映射配置resultMap一样,处理器映射器也是可以有多个,处理器映射器的作用就是根据HTTP请求(HttpServletRequest),作为参数传入到getHandler()方法中,该方法返回一个处理器执行链,我们就能根据这个执行链得到匹配的处理器。