Spring mvc HandlerMapping 實現機制

概述

當DispatcherServlet接受到客戶端的請求後,SpringMVC 經過 HandlerMapping 找到請求的Controller。
HandlerMapping 在這裏起到路由的做用,負責找到請求的Controller。web

Spring MVC 默認提供了4種 HandlerMapping的實現

  1. org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
    經過配置請求路徑和Controller映射創建關係,找到相應的Controller
  2. org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping
    經過 Controller 的類名找到請求的Controller。
  3. org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
    經過定義的 beanName 進行查找要請求的Controller
  4. org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
    經過註解 @RequestMapping("/userlist") 來查找對應的Controller。

HandlerMapping 的4種配置

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="/userlist.htm">userController</prop>
        </props>
    </property>
</bean>
    
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>

<bean id="userController" name="/users" class="com.qunar.web.controller.UserController"></bean>

UserController

@Controller
public class UserController extends AbstractController {

    @Override
    @RequestMapping("/userlist")
    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        
        List<User> userList = new ArrayList<User>();
        
        userList.add(new User("zhangsan", 18));
        userList.add(new User("list", 16));
        
        return new ModelAndView("userList", "users", userList);
    }
}

HandlerMapping 4種訪問路徑

  1. SimpleUrlHandlerMapping
    訪問方式: http://ip:port/project/userlist.htm
  2. ControllerClassNameHandlerMapping
    訪問方式: http://ip:port/project/user
    注:類的首字母要小寫
  3. BeanNameUrlHandlerMapping
    訪問方式: http://ip:port/project/users
    注:bean name屬性必需要以「/」開頭。
  4. DefaultAnnotationHandlerMapping
    訪問方式: http://ip:port/project/userlist
    注:@RequestMapping("/userlist")定義的路徑

HandlerMapping 初始化原理

繼續上一篇Spring mvc DispatchServlet 實現原理 初始化DispatchServlet的時候,執行了初始化HandlerMapping操做。spring

initHandlerMapping() 方法

  1. 判斷detectAllHandlerMappings是否爲true,若是爲true,則加載當前系統中全部實現了HandlerMapping接口的bean。
  2. 若是爲false,則加載bean名稱爲「handlermapping」的HandlerMapping實現類。
  3. 若是尚未找到HandlerMapping,則加載SpvingMVC 配置文件中,默認配置的HandlerMapping。

detectAllHandlerMappings 設置

detectAllHandlerMappings 默認爲true,若是隻想加載本身指定的HandlerMapping,請使用下面的方式指定mvc

若是這樣指定,則Spring MVC 只會加載這個HandlerMapping,而不會加載配置的其它的HandlerMapping。app

SimpleUrlHandlerMapping

以SimpleUrlHandlerMapping 爲例,簡單分析下HandlerMappingide

從SimpleUrlHandlerMapping 類結構中咱們能夠發現urlMap屬性。這個urlMap中保存了xml中配置的映射關係,經過setMappings方法填充到urlMap中。url

這個urlMap就充當了SpringMVC的路由功能。spa

每一個HandlerMapping都會有一個這樣的Map。.net

DispatcherServlet.doDispatch()

當用戶請求時,真正的請求會執行到DispatcherServlet的doDispatch()方法。3d

  1. 經過getHandler() 方法去查找HandlerMapping中查找對應的Controller,並封裝成HandlerExecutionChain。
  2. 若是找不到,則執行noHandlerFound() 方法。

getHandler() 方法

迭代查找全部的HandlerMapping,若是找到則直接返回。code

noHandlerFound() 方法

若是找不到Controller 則後臺拋出異常或響應給前臺 404。

相關文章
相關標籤/搜索