經過本身實現接口來加深理解SpringMVC的執行流程

功能介紹

上篇文章【從源碼角度瞭解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的執行流程有個更加具象的理解。

相關文章
相關標籤/搜索