zoukankan      html  css  js  c++  java
  • 通过自己实现接口来加深理解SpringMVC的执行流程

    功能介绍

    上篇文章【从源码角度了解SpringMVC的执行流程】通过接口源码向大家介绍了SpringMVC的执行流程,主要偏重于源码。这篇文件我们来自己实现那几个关键接口,来真实体验下SpringMVC关键的流程,以此来加深理解。功能很简单,通过访问一个地址 /mymvc 来自动跳转到工程首页,但是我们不用SpringMVC自带的Controller等组件,完全自己手动开发。工程结构如下图

    代码流程

    将自定义的实现类放入Ioc容器中。

    @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。

    下面的代码是自定义HandlerMapping继承于AbstractHandlerMapping 。其中AbstractHandlerMapping 实现了HandlerMapping接口。这也是代码通常的结构。定义一个接口,抽象类实现接口完善一些基础代码,并将那些可以扩展的功能再暴露出去,这样我们再开发时只需要关注自己扩展的功能即可,不需要将接口所有的方法都再实现一遍,大大减少了开发成本。

    新建自定义的处理器MyHandler返回。这里有一点需要注意,就是需要设置排序号,否则SpringMVC会先执行SimpleUrlHandlerMapping,这个类作为SpringMVC中最后执行的类,如果没有找到处理器,则会返回异常,所以自定义的HandlerMapping排序号必须大于这个类的排序号,先于此类执行。

    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判断适配器是否适配上面获取的处理器,为什么会有适配器这一层逻辑上篇代码也介绍过了。

    下面代码为自定义HandlerAdapter,supports逻辑很简单,判断处理器类型是否为MyHandler。

    public class MyHandlerAdapter implements HandlerAdapter {
        @Override
        public boolean supports(Object handler) {
            if (handler instanceof MyHandler) {
                return  true;
            }
            return false;
        }
    
    

    适配器调用处理器

    调用自定义处理器的handler方法,返回逻辑视图名,并封装为ModelAndView。

    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 作为逻辑视图名。

    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的执行流程有个更加具象的理解。

  • 相关阅读:
    VC 中与字符串相关的宏 _T、TEXT,_TEXT、L 的作用(简单明了)
    内存泄露检测工具(25款)
    谈VC++对象模型
    函数调用堆栈分析
    一个跨平台的 C++ 内存泄漏检测器
    网站架构资料收集整理
    分布式缓存系统memcached简介与实践
    反向代理(Reverse Proxy)
    squid和varnish的小结
    ajax简单后台交互
  • 原文地址:https://www.cnblogs.com/LuxBai/p/12203341.html
Copyright © 2011-2022 走看看