在穿越了 Web 容器和Web 应用以后,HTTP 请求将被投送到 Spring 框架,咱们继续剖析后续流程。Web 应用与 Spring MVC 的衔接是经过配置文件 mvc-servlet.xml 完成的,咱们经过这份配置文件定义构成 Spring MVC 的各类核心组件和初始化配置,其中包括:控制器 Controller、视图解析器 ViewResolver、视图 View 等等。不一样组件分别承担不一样的功能,在介绍 Spring 框架处理 HTTP 请求流程以前,咱们照例先了解一下这些核心组件。前端
咱们应用开发者在使用 Spring 时接触最多的就是各类注解,包括:@Component、@Controller、@Service、@Repository 等,这些都是 Spring 的核心组件。除此以外,咱们还会使用 @RequestMapping、@RequestParam、@PathVariable、@RequestBody 等辅助性注解:数据库
模型 Model:封装了业务数据,主要以 POJO 形式存在。后端
控制器 Controller:主要负责具体业务流程的调度控制,以及调用业务逻辑服务 Service。 控制器 Controller 处理完 HTTP 请求以后返回 ModelAndView 对象给前置分发器 DispatcherServlet,ModelAndView 中包含了模型 Model 对象和视图 View 名称。前端工程化
视图 View:负责渲染呈现模型 Model 数据,以及提供表单供用户录入各类业务数据。服务器
视图解析器 ViewResolver:负责根据已知的视图名称获取一个特定视图 View 子类实例对象。微信
处理器映射 HandlerMapping:主要负责控制器 Controller 的注册和查找,由应用上下文 ApplicationContext 持有。具体实现上它拥有 HashMap<String, Object> 类型的成员属性 handlerMap,其中 key 是 HTTP 请求的 URI 信息,value 能够是一个字符串或者处理请求的 HandlerExecutionChain。若是是 String,则视为 Spring Bean 名称。架构
服务 Service:主要负责实现具体的业务逻辑。mvc
数据存储对象 Repository:也称为数据访问对象 DAO(Data Access Object),无论采用什么开发框架,大部分应用都须要跟数据库交互,DAO 就是将访问数据库操做作了封装,隔离了 SQL 相关复杂度。 app
Web 容器监听主机特定端口,每当有请求抵达时,Web 容器最终将调用 Servlet 的 service 方法处理 HTTP 请求。在 Spring Web 应用中,接收 HTTP 请求的 Servlet 就是前置分发器 DispatcherServlet。框架
在前置分发器 DispatcherServlet 的 service 方法中判断 HTTP 请求类型,包括:GET、POST、PUT、PATCH 等等,而后再决定调用 doGet()、doPost()、doPut() 等方法。
在 doGet()、doPost()、doPut() 等方法中执行 processRequest() 方法,完成请求上下文的的初始化。
调用 doService() 方法,进一步执行 doDispatch() 方法。
在 doDispatch() 方法中获取 HTTP 请求的 mappedHandler 和 HandlerAdapter,而后再发起对业务控制器 Controller 的调用以及后续流程,等待处理结果再构建响应数据。
在填充处理器 Handler 入参的过程当中,Spring 还会根据配置作些预处理工做:
Spring Web 应用架构经历了多个阶段的发展,最初主流的前端视图技术就是 JSP,在此基础上又演化出了三剑客框架 SSH(Struts\Spring\Hibernate),但这时候先后端其实仍是耦合在一块儿的,不论是 JSP 仍是 SSH,在前面 Spring 框架处理 HTTP 请求的流程中,必需要依赖视图解析器 ViewResolver 和视图 View。
从 Spring 诞生到如今已经15年多了,它关联的后端技术演化其实没有前端那么快,主要缘由就是前端需求愈来愈丰富多样,前端视图层的开发工做量和复杂度不断增长。在这样的背景之下,愈来愈多的前端工程化解决方案涌现,其中最有成效的就是先后端分离,从 AngularJS\Backbone.js 到如今 React\Vue 等。在这种先后端分离架构下,前端就所有由静态资源(HTML\Javascript\CSS)等构成,能够独立部署在 Web 服务器当中,这样 Spring 框架就不须要再处理视图相关的内容,控制器 Controller 再也不返回 ModelAndView,只须要反馈模型数据了。
本系列其余文章索引以下: