深入理解SpringMVC DispatcherServlet源码及全流程原理
SpringMVC是Spring框架中的一个模块,用于构建基于MVC(Model-View-Controller)设计模式的Web应用程序。核心组件 DispatcherServlet
负责请求的处理和响应的生成。本文将深入探讨 DispatcherServlet
的源码,以理解SpringMVC的全流程原理。
目录
- DispatcherServlet概述
- DispatcherServlet初始化
- 请求处理流程
- 处理器映射
- 处理器适配
- 视图解析
- 总结
DispatcherServlet概述
DispatcherServlet
是SpringMVC的前端控制器(Front Controller),它负责拦截所有进入应用的HTTP请求,分发请求给相应的处理器,并处理返回的响应。DispatcherServlet
的主要职责包括:
- 初始化WebApplicationContext
- 加载各种组件(如HandlerMapping、HandlerAdapter等)
- 分发请求
- 视图解析和渲染
DispatcherServlet初始化
DispatcherServlet
的初始化过程包括创建和配置Spring的WebApplicationContext以及加载各种必要的组件。下面是 DispatcherServlet
初始化的主要步骤:
- 初始化WebApplicationContext:
protected WebApplicationContext initWebApplicationContext() {
// 获取现有的WebApplicationContext
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = createWebApplicationContext(rootContext);
// 配置WebApplicationContext
configureAndRefreshWebApplicationContext(wac);
return wac;
}
- 加载配置文件和初始化组件:
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
请求处理流程
当一个HTTP请求到达时,DispatcherServlet
将按以下步骤处理请求:
- 请求接收:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
ModelAndView mv = null;
Exception dispatchException = null;
try {
// 检查并包装Multipart请求
processedRequest = checkMultipart(request);
// 获得处理器
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 获得处理器适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 执行处理器
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 处理视图
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
dispatchException = ex;
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
}
- 检查Multipart请求:
protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
return this.multipartResolver.resolveMultipart(request);
}
return request;
}
- 获取处理器:
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}
- 获取处理器适配器:
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
for (HandlerAdapter ha : this.handlerAdapters) {
if (ha.supports(handler)) {
return ha;
}
}
throw new ServletException("No adapter for handler [" + handler + "]");
}
- 处理视图:
protected void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {
if (exception != null) {
if (mv == null) {
throw exception;
}
mv.addObject("exception", exception);
}
if (mv != null) {
render(mv, request, response);
}
}
处理器映射
处理器映射(Handler Mapping)负责将请求URL映射到相应的处理器。常用的处理器映射有:
- RequestMappingHandlerMapping:基于注解的处理器映射。
- BeanNameUrlHandlerMapping:基于Bean名称的处理器映射。
public HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
return handlerMethod != null ? new HandlerExecutionChain(handlerMethod) : null;
}
处理器适配
处理器适配(Handler Adapter)负责调用处理器方法。常用的处理器适配有:
- RequestMappingHandlerAdapter:适配使用@RequestMapping注解的方法。
- HttpRequestHandlerAdapter:适配实现HttpRequestHandler接口的处理器。
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return ((HandlerMethod) handler).invokeForRequest(request, response);
}
视图解析
视图解析(View Resolver)负责将逻辑视图名称解析为实际视图对象,并渲染视图。常用的视图解析器有:
- InternalResourceViewResolver:解析JSP视图。
- ThymeleafViewResolver:解析Thymeleaf视图。
public View resolveViewName(String viewName, Locale locale) throws Exception {
return getView(viewName, locale);
}
protected View getView(String viewName, Locale locale) throws Exception {
return (viewName != null ? new InternalResourceView(viewName) : null);
}
分析说明表
阶段 | 组件 | 主要职责 | 代码示例 |
---|---|---|---|
初始化 | DispatcherServlet | 初始化WebApplicationContext,加载组件 | initWebApplicationContext() ,initStrategies() |
请求接收 | DispatcherServlet | 接收HTTP请求,检查Multipart请求 | doDispatch() ,checkMultipart() |
获取处理器 | HandlerMapping | 将请求URL映射到处理器 | getHandler() |
获取处理器适配器 | HandlerAdapter | 调用处理器方法 | getHandlerAdapter() ,handle() |
视图解析 | ViewResolver | 将逻辑视图名称解析为视图对象,并渲染视图 | resolveViewName() ,getView() |
总结
通过对 DispatcherServlet
源码的深入剖析,我们了解了SpringMVC请求处理的全流程。DispatcherServlet
作为前端控制器,负责请求的接收和分发,处理器映射和适配负责将请求分派到具体的处理器方法,视图解析器负责生成和渲染视图。理解这些核心组件及其交互原理,有助于开发者更好地使用和扩展SpringMVC框架。