互联网架构-SpringMVC源码深度解析-031:HandlerAdapter适配器模式源码分析

蚂蚁课堂第5期视频笔记 专栏收录该内容
59 篇文章 8 订阅

1 SpringMVC底层执行流程简单回顾

课题内容:

  1. 什么是适配器模式?应用场景有哪些?
  2. 为什么SpringMVC需要通过适配器执行hanlder
  3. SpringMVC适配器模式源码分析
  4. SpringMVC框架中如何自定义适配器

思考:SpringMVC中为什么需要使用适配器执行请求方法?需要使用handler(已获取)获取对应的适配器,然后再通过适配器执行请求方法?

2 HandlerAdapter适配器有那些分类

HandlerAdapter适配器分类
在这里插入图片描述
SpringMVC适配器模式源码分析

  1. 使用getHandlerAdapter获取对应的hanlder的具体HandlerAdapter
  2. HandlerAdapter接口有如下的子类处理请求适配器
    2.1 继承Controller方式所使用的适配器:SimpleControllerHandlerAdapter
    2.2 HTTP请求处理器适配器:HttpRequestHandlerAdapter
    3.3 注解方式(@Controller)的处理器适配器:RequestMappingHandlerAdapter

Handler有多种类型,循环判断类型找到具体的适配器,包装进行调用执行方法。

3 SpringMVC为什么要采用适配器模式

Handler有多种不同类型,如果不采用适配器的话:
If(hanlder instanceof Controller){
// 执行Controller适配器
}
If(hanlder instanceof HttpControler){
// 执行HttpController
}
If(hanlder instanceof ServletControler){
// 执行HttpController
}
If(hanlder instanceof AnnotationControler){
// 执行AnnotationController
}
扩展性差
SpringMVC通过使用适配器针对不同handler类型找到不同的适配器实现执行。

4 HandlerAdapter适配器源码分析

什么是适配器模式
将一个系统的接口转换成另外一种形式,从而使原来不能直接调用的接口变得可以调用。
适配器模式应用场景

  1. Mybatis多种日志框架的整合
  2. SpringMVC适配器模式
  3. 新老版本的兼容问题

简单模拟springMVC适配器模式运用
Adapter

public interface HandlerAdapter {

    /**
     * 根据handler判断是哪个HandlerAdapter类型,如果找到对应类型返回true
     * @param handler
     * @return
     */
    boolean supports(Object handler);

    /**
     * 执行请求方法
     */
    void handle(Object handler);
}
public class AnnotationHandlerAdapter implements HandlerAdapter {

    /**
     * 注解形式的适配器
     *
     * @param handler
     * @return
     */
    public boolean supports(Object handler) {
        return (handler instanceof AnnotationController);
    }

    public void handle(Object handler) {
        ((AnnotationController) handler).handler();
    }
}
public class HttpRequestHandlerAdapter implements HandlerAdapter {

    /**
     * Http类型适配器
     *
     * @param handler
     * @return
     */
    public boolean supports(Object handler) {
        return (handler instanceof HttpController);
    }

    public void handle(Object handler) {
        ((HttpController) handler).handler();
    }
}

Handler

public interface Controller {
    void handler();
}
public class AnnotationController implements Controller {

    public void handler() {
        System.out.println("AnnotationController");
    }
}
public class HttpController implements Controller {

    public void handler() {
        System.out.println("HttpController");
    }
}

5 手写HandlerAdapter适配器模式01

DispatcherServlet

public class DispatcherServlet {

    private List<HandlerAdapter> handlerAdapters;

    public DispatcherServlet(){
        handlerAdapters = new ArrayList<HandlerAdapter>();
        handlerAdapters.add(new AnnotationHandlerAdapter());
        handlerAdapters.add(new HttpRequestHandlerAdapter());
    }
    public void dispatcher(){
        // 1.已经获取到handler
        AnnotationController handler = new AnnotationController();
        // 2.获取具体的适配器
        HandlerAdapter handlerAdapter = getHandlerAdapter(handler);
        // 3.执行请求方案
        handlerAdapter.handle(handler);

    }

    public HandlerAdapter getHandlerAdapter(Controller controller) {
        if (this.handlerAdapters != null) {
            for (HandlerAdapter ha : this.handlerAdapters) {
                if (ha.supports(controller)) {
                    return ha;
                }
            }
        }
        return null;
    }

    public static void main(String[] args) {
        new DispatcherServlet().dispatcher();
    }
}

运行结果:
在这里插入图片描述

6 手写HandlerAdapter适配器模式02

断点调试流程:
在这里插入图片描述

  • 0
    点赞
  • 1
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值