SpringMVC是Java企业级Web应用的一种流行框架,遵循MVC(Model-View-Controller)设计模式。在了解它的执行流程之前,我们必须了解它的核心前端控制器:DispatcherServlet
DispatcherServlet
是 Spring Web MVC 框架的核心入口点,它是一个实现了 javax.servlet.http.HttpServlet
接口的 Servlet 类,负责处理和调度 Web 请求。在 Spring MVC 应用程序中,DispatcherServlet
扮演着前端控制器的角色,控制着整个请求处理流程,包括但不限于以下几个方面:
-
初始化配置: 当 Web 应用启动时,Web 容器加载并实例化
DispatcherServlet
,然后调用其init()
方法完成初始化。在这个阶段,DispatcherServlet
将读取 Spring 配置文件(通常为applicationContext.xml
或servlet-name-servlet.xml
),构建 Spring WebApplicationContext,加载各种 MVC 组件(如 HandlerMappings, HandlerAdapters, ViewResolvers 等)。 -
请求处理流程:
- 接收请求:当 HTTP 请求到达服务器时,容器将请求交给
DispatcherServlet
。 - 处理器映射:
DispatcherServlet
使用已注册的 HandlerMapping 来定位哪个处理器(即 Controller 中的方法)应当处理这个请求。这个映射通常是基于 URL 和 HTTP 方法来进行的。 - 调用控制器方法:一旦找到合适的处理器,
DispatcherServlet
通过 HandlerAdapter 来执行对应的控制器方法。 - 数据准备与模型填充:控制器方法执行业务逻辑,并将处理结果放入 Model 对象中。
- 视图解析:处理完成后,控制器方法可能返回一个逻辑视图名称,
DispatcherServlet
通过 ViewResolver 将逻辑名称解析为实际的 View 实例。 - 视图渲染:最后,
DispatcherServlet
将 Model 数据传递给 View 进行渲染,生成最终的响应内容(通常是 HTML 页面)并将其发送回客户端。
- 接收请求:当 HTTP 请求到达服务器时,容器将请求交给
以下是一个简化的 DispatcherServlet
生命周期内关键方法的代码示例:
// org.springframework.web.servlet.DispatcherServlet 类的部分伪代码
public class DispatcherServlet extends HttpServlet {
// 初始化方法,由容器在启动时调用
@Override
public void init(ServletConfig config) throws ServletException {
// 初始化 WebApplicationContext
this.webApplicationContext = initWebApplicationContext(config);
// 初始化其他 MVC 组件
initStrategies(context);
}
// 处理 HTTP 请求的核心方法
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 其实真正处理请求的是 doService 方法
doService(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doService(req, resp);
}
// 处理通用请求的服务方法
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 获取 HandlerExecutionChain(包含了选定的处理器和一系列预处理器、后处理器)
HandlerExecutionChain mappedHandler = getHandler(request);
if (mappedHandler != null) {
// 创建 ModelAndViewContainer 用于存储模型和视图信息
ModelAndView mvContainer = new ModelAndView();
// 创建 NativeWebRequest 对象,封装原始的请求和响应对象
NativeWebRequest webRequest = createNativeWebRequest(request, response);
// 创建 LocaleContextResolver 并设置本地化上下文
applyLocaleContext(webRequest);
// 执行预处理拦截器链
applyPreHandle(mappedHandler, webRequest);
// 执行处理器(Controller 方法)
mvContainer = invokeHandler(mappedHandler, webRequest, mvContainer);
// 执行后处理拦截器链
applyDefaultViewName(request, mvContainer);
applyPostHandle(mappedHandler, mvContainer, webRequest);
// 视图解析和渲染
processDispatchResult(mappedHandler, mvContainer, webRequest, response);
} else {
noHandlerFound(request, response);
}
}
// ... 其他实现细节,如视图解析、拦截器处理等 ...
}
请注意,上述代码仅为简化版示意,实际源码更为复杂和完善,包括了大量的错误处理、拦截器支持、异步请求处理等内容。为了更好地理解其工作原理,建议查看 Spring Framework 官方源码或官方文档。
所以,我们大致能够明白SpringMVC的执行流程了,如图:
总结,我们可以得知SpringMVC的执行流程为:
首先收到客户端的请求过后,会去找到前端核心控制器:DispatcherServlet
,然后去找到HandlerMapping (处理器映射器)查找处理请求的Handler(也就是我们的Controller)DispatcherServlet调用适配器
HandlerAdapter,按照特定的规则去执行 Controller (Handler)返回一个 ModelAndView 对象,并且返回给DispatcherServlet前端控制器。然后找到视图解析器进行解析,最后将解析的结果返回给前端,进行渲染。