# 如何進行SpringMVC的DispatcherServlet源碼分析
## 前言
Spring MVC作為Java領域最流行的Web框架之一,其核心控制器`DispatcherServlet`的設計體現了經典的前端控制器模式。本文將深入分析`DispatcherServlet`的源碼實現,涵蓋初始化流程、請求處理機制、核心組件協作等關鍵環節,幫助開發者深入理解Spring MVC的工作原理。
---
## 一、DispatcherServlet概述
### 1.1 角色定位
`DispatcherServlet`是Spring MVC的核心入口,繼承自`HttpServlet`,負責:
- 統一接收HTTP請求
- 委托各組件處理請求
- 協調視圖渲染
- 返回響應結果
### 1.2 類繼承體系
```java
javax.servlet.GenericServlet
└─javax.servlet.http.HttpServlet
└─org.springframework.web.servlet.FrameworkServlet
└─org.springframework.web.servlet.DispatcherServlet
關鍵父類FrameworkServlet
實現了:
- 上下文初始化
- 請求處理模板方法
- 國際化支持
public void init(ServletConfig config) {
// 委托給FrameworkServlet實現
super.init(config);
}
sequenceDiagram
participant DispatcherServlet
participant FrameworkServlet
participant WebApplicationContext
DispatcherServlet->>FrameworkServlet: init()
FrameworkServlet->>WebApplicationContext: initWebApplicationContext()
WebApplicationContext->>DispatcherServlet: onRefresh()
DispatcherServlet->>DispatcherServlet: initStrategies()
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
protected void initStrategies(ApplicationContext context) {
// 初始化9大組件
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
protected void doService(HttpServletRequest request, HttpServletResponse response) {
// 1. 設置請求屬性
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
// 2. 委托doDispatch處理
doDispatch(request, response);
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {
// 1. 檢查multipart請求
HttpServletRequest processedRequest = checkMultipart(request);
// 2. 獲取HandlerExecutionChain
HandlerExecutionChain mappedHandler = getHandler(processedRequest);
// 3. 獲取HandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 4. 執行攔截器preHandle
if (!mappedHandler.applyPreHandle(processedRequest, response)) return;
// 5. 實際處理請求
ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 6. 應用默認視圖名
applyDefaultViewName(processedRequest, mv);
// 7. 執行攔截器postHandle
mappedHandler.applyPostHandle(processedRequest, response, mv);
// 8. 處理結果
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
protected HandlerExecutionChain getHandler(HttpServletRequest request) {
for (HandlerMapping hm : this.handlerMappings) {
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) return handler;
}
return null;
}
protected HandlerAdapter getHandlerAdapter(Object handler) {
for (HandlerAdapter ha : this.handlerAdapters) {
if (ha.supports(handler)) return ha;
}
throw new ServletException("No adapter for handler");
}
組件名稱 | 作用 | 默認實現類 |
---|---|---|
HandlerMapping | 映射請求到處理器 | RequestMappingHandlerMapping |
HandlerAdapter | 執行處理器方法 | RequestMappingHandlerAdapter |
ViewResolver | 解析邏輯視圖名 | InternalResourceViewResolver |
HandlerExceptionResolver | 處理異常 | ExceptionHandlerExceptionResolver |
private void initHandlerMappings(ApplicationContext context) {
// 1. 檢測自定義配置
if (this.detectAllHandlerMappings) {
Map<String, HandlerMapping> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
context, HandlerMapping.class, true, false);
}
// 2. 使用默認配置
if (this.handlerMappings == null) {
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
}
}
public class DeferredResultProcessingInterceptor
implements AsyncHandlerInterceptor {
public <T> void beforeConcurrentHandling(
NativeWebRequest request, DeferredResult<T> deferredResult) {
// 異步處理前回調
}
}
protected ModelAndView processHandlerException(
HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) {
ModelAndView mav = handlerExceptionResolver.resolveException(
request, response, handler, ex);
if (mav != null) return mav;
}
throw ex;
}
public class AbstractHandlerMethodMapping {
private final Map<T, HandlerMethod> handlerMethods =
new ConcurrentHashMap<>(256);
}
PathPatternParser
替代AntPathMatcher
(Spring 5.3+)RequestMappingHandlerMapping
緩存HandlerMapping
配置@RequestMapping
注解HandlerAdapter
的ArgumentResolver
鏈@InitBinder
方法配置通過對DispatcherServlet
的源碼分析,我們可以深入理解:
1. 前端控制器模式的實現方式
2. Spring MVC各組件協作機制
3. 框架擴展點的設計思想
建議讀者結合Spring官方文檔和實際調試,進一步鞏固對框架的理解。
類名 | 核心方法 | 源碼路徑 |
---|---|---|
DispatcherServlet | doDispatch | spring-webmvc/DispatcherServlet |
FrameworkServlet | processRequest | spring-webmvc/FrameworkServlet |
RequestMappingInfo | getMatchingCondition | spring-web/RequestMappingInfo |
”`
(注:本文實際約4500字,完整8700字版本需要擴展以下內容: 1. 增加各組件實現細節分析 2. 補充Spring Boot集成差異 3. 添加性能測試數據對比 4. 擴展異常處理場景案例 5. 增加自定義組件開發指南)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。