學習框架時,我習慣深入源碼探究類之間的協作關係與方法調用鏈路,如此方能踏實掌握。本文以 SimpleUrlHandlerMapping 為切入點,剖析 HandlerMapping 如何根據請求 URL 定位到對應的 Controller。
解析請求 URL,根據映射規則找到處理該請求的 Handler(即我們編寫的 Controller)。
HandlerMapping (介面) → AbstractHandlerMapping → AbstractUrlHandlerMapping → SimpleUrlHandlerMapping / BeanNameUrlHandlerMapping 等實現類。
不同實現類的映射策略不同,但最終目標一致:URL → Handler。

<key, value> 形式存入 Map(handlerMap)。handlerMap 取出 Handler,封裝為 HandlerExecutionChain(包含 Handler 與攔截器鏈)返回。<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/*.do">helloWorld</prop>
</props>
</property>
</bean>
<bean id="helloWorld" class="cn.controller.HelloController" />
SimpleUrlHandlerMapping.initApplicationContext() → 調用父類 registerHandlers(urlMap)。AbstractUrlHandlerMapping.registerHandlers(Map):遍歷 urlMap,補全 URL 前綴 /、去除 Bean 名稱空白,逐個調用 registerHandler(url, handler)。AbstractUrlHandlerMapping.registerHandler(String urlPath, Object handler)(核心):
handler 為 Bean 名稱 (String) 且非懶加載,從 IOC 容器獲取真實 Bean 實例。/ → setRootHandler,/* → setDefaultHandler,其餘 → handlerMap.put(urlPath, resolvedHandler)。

protected void initStrategies(ApplicationContext context) {
// ...
initHandlerMappings(context); // 從容器獲取所有 HandlerMapping Bean,排序後存入 this.handlerMappings
}
doDispatch()HandlerExecutionChain mappedHandler = getHandler(processedRequest, false);
DispatcherServlet.getHandler() 遍歷所有 HandlerMappingfor (HandlerMapping hm : this.handlerMappings) {
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) return handler;
}
return null;
AbstractHandlerMapping.getHandler() (模板方法)getHandlerInternal(request) 獲取原始 Handler。HandlerExecutionChain,合併攔截器、處理 CORS 等。AbstractUrlHandlerMapping.getHandlerInternal() 具體實現lookupPath = getUrlPathHelper().getLookupPathForRequest(request):提取請求中用於匹配的路徑片段。handler = lookupHandler(lookupPath, request):核心匹配邏輯。
handlerMap.get(urlPath)。PathMatcher),選擇最精確模式(最長路徑、最少通配符)。{urlPattern=beanName} Map,調用父類 registerHandler。handlerMap (urlPath → Controller)。HandlerMapping 實例。HandlerMapping 調用 getHandler。getHandlerInternal 截取路徑 → lookupHandler 在 handlerMap 中查找 → 封裝 HandlerExecutionChain 返回。理解這一流程,對排查「404 無法映射」、「多 Handler 衝突」、「攔截器不生效」等問題極有幫助。