url 和 Controller 的對應關係

很多人對這一塊比較茫然,比如在網頁輸入 /index/test.do就找到對了對應的Controller 類。url和Controller 關係怎麼建立的。

AbstractHandlerMethodMapping實現了InitializingBean接口。說明這個類會在依賴注入的初始化開始執行,也就是Init-method那個解析地方處理這個擴展點。其源碼分析:



在AbstractHandlerMethodMapping#isHandler中判斷了類上使用Controller或RequestMapping其中至少一個註解就可以.


在initHandlerMethods調用detectHandlerMethods方法

protected void detectHandlerMethods(final Object handler) {
   //獲取原始的Class<?> 也就是 public void com.jshx.estate.page.controller.PageCoreController類型這種
   Class<?> handlerType = (handler instanceof String ?
         obtainApplicationContext().getType((String) handler) : handler.getClass());

   if (handlerType != null) {
      final Class<?> userType = ClassUtils.getUserClass(handlerType);
      Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
            (MethodIntrospector.MetadataLookup<T>) method -> {
               try {
                  //獲取該controller類的所有url
                  return getMappingForMethod(method, userType);
               } catch (Throwable ex) {
                  throw new IllegalStateException("Invalid mapping on handler class [" +
                        userType.getName() + "]: " + method, ex);
               }
            });
      if (logger.isDebugEnabled()) {
         logger.debug(methods.size() + " request handler methods found on " + userType + ": " + methods);
      }
      //對過濾到的每個method進行註冊registerHandlerMethod
      methods.forEach((method, mapping) -> {
         Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
         registerHandlerMethod(handler, invocableMethod, mapping);
      });
   }
}

detectHandlerMethods調用getMappingForMethod,這個方法由子類RequestMappingHandlerMapping裏面進行實現

回到detectHandlerMethods方法中,開始調用registerHandlerMethod方法


這樣就完成了映射關係。說白了就是將完整/app/core/getArticles.do 和對應的public..... PageCoreController.getArticles()放到map中。用戶輸入鏈接後,通過Dispatcherservlet.doDispatch()獲取url匹配到對應的類方法,然後通過反射實例化來處理邏輯。


上一篇: IOC容器中常用擴展點

下一篇: DispatcherServlet接收請求

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章