上篇文章【從源碼角度瞭解SpringMVC的執行流程】經過接口源碼向你們介紹了SpringMVC的執行流程,主要偏重於源碼。這篇文件咱們來本身實現那幾個關鍵接口,來真實體驗下SpringMVC關鍵的流程,以此來加深理解。功能很簡單,經過訪問一個地址 /mymvc 來自動跳轉到工程首頁,可是咱們不用SpringMVC自帶的Controller等組件,徹底本身手動開發。工程結構以下圖html
將自定義的實現類放入Ioc容器中。java
@Configuration public class MyConfig { @Bean public HandlerMapping myHandlerMapping() { return new MyHandlerMapping(); } @Bean public HandlerAdapter myHandlerAdapter() { return new MyHandlerAdapter(); } @Bean public ViewResolver myViewResolver() { return new MyViewResolver(); } }
獲取實現了HandlerMapping接口的類調用getHandler獲取handler。mvc
下面的代碼是自定義HandlerMapping繼承於AbstractHandlerMapping 。其中AbstractHandlerMapping 實現了HandlerMapping接口。這也是代碼一般的結構。定義一個接口,抽象類實現接口完善一些基礎代碼,並將那些能夠擴展的功能再暴露出去,這樣咱們再開發時只須要關注本身擴展的功能便可,不須要將接口全部的方法都再實現一遍,大大減小了開發成本。app
新建自定義的處理器MyHandler返回。這裏有一點須要注意,就是須要設置排序號,不然SpringMVC會先執行SimpleUrlHandlerMapping,這個類做爲SpringMVC中最後執行的類,若是沒有找處處理器,則會返回異常,因此自定義的HandlerMapping排序號必須大於這個類的排序號,先於此類執行。ide
public class MyHandlerMapping extends AbstractHandlerMapping { @Override protected Object getHandlerInternal(HttpServletRequest request) throws Exception { Object handler = null; String requestUri = getUrlPathHelper().getRequestUri(request); if (requestUri.equals("/mymvc")) { handler = new MyHandler(); } return handler; } @Override public int getOrder() { return 1; } }
獲取實現了HandlerAdapter接口的類調用supports判斷適配器是否適配上面獲取的處理器,爲何會有適配器這一層邏輯上篇代碼也介紹過了。3d
下面代碼爲自定義HandlerAdapter,supports邏輯很簡單,判斷處理器類型是否爲MyHandler。code
public class MyHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { if (handler instanceof MyHandler) { return true; } return false; }
調用自定義處理器的handler方法,返回邏輯視圖名,並封裝爲ModelAndView。htm
public class MyHandlerAdapter implements HandlerAdapter { @Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { MyHandler myHandler = (MyHandler) handler; String result = myHandler.handler(); ModelAndView mv = new ModelAndView(); mv.setViewName(result); return mv; }
自定義處理器,返回 myview 做爲邏輯視圖名。blog
public class MyHandler { public String handler() { return "myview"; } }
判斷邏輯視圖名爲 myview 新建視圖返回。排序
public class MyViewResolver implements ViewResolver { @Override public View resolveViewName(String viewName, Locale locale) throws Exception { View view = null; if ("myview".equals(viewName)) { view = new MyView(); } return view; } }
直接跳轉到首頁。
public class MyView implements View { @Override public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { String path = "http://localhost:8080/"; response.sendRedirect(path); } @Override public String getContentType() { return "text/html;charset=ISO-8859-1"; } }
上面代碼邏輯很簡單,你們也能夠照着這個思路本身動手開發自定義的擴展功能,本身DUBUG體會一下總體流程,我相信會對SpringMVC的執行流程有個更加具象的理解。