很多人對這一塊比較茫然,比如在網頁輸入 /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容器中常用擴展點