文档章节

SpringMVC源码深度解析之HandlerAdapter适配器模式源码分析

须臾之余
 须臾之余
发布于 08/02 17:40
字数 729
阅读 51
收藏 0

SpringMVC中的HandlerAdapter适配器

什么是适配器模式

定义:将一个系统的接口转换成另外一种形式,从而使原来不能直接调用的接口变得可以调用。

适配器模式应用场景

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

SpringMVC适配器模式源码分析

1、通过URL找到具体的请求方法

mappedHandler = this.getHandler(processedRequest);

2、使用getHandlerAdapter获取对应的hanlder的具体HandlerAdapter,然后通过具体的适配器执行方法

HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());

在这里进行初始化三个适配器

先走父类

返回true

protected boolean supportsInternal(HandlerMethod handlerMethod) {
    return true;
}

拿到对应的适配器

HandlerAdapter接口看下所有适配器类型

下面看下这几种适配器:

AbstractHandlerMethodAdapter implements HandlerAdapter

public final boolean supports(Object handler) {
    return handler instanceof HandlerMethod && this.supportsInternal((HandlerMethod)handler);
}

HttpRequestHandlerAdapter implements HandlerAdapter

public boolean supports(Object handler) {
    return handler instanceof HttpRequestHandler;
}

RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter

protected boolean supportsInternal(HandlerMethod handlerMethod) {
    return true;
}

SimpleControllerHandlerAdapter implements HandlerAdapter

public boolean supports(Object handler) {
    return handler instanceof Controller;
}

SimpleServletHandlerAdapter implements HandlerAdapter

public boolean supports(Object handler) {
    return handler instanceof Servlet;
}
  • 继承Controller方式所使用的适配器:SimpleControllerHandlerAdapter
  • HTTP请求处理器适配器:HttpRequestHandlerAdapter
  • 注解方式(@Controller)的处理器适配器:RequestMappingHandlerAdapter

如果不采用适配器的话

If(hanlder instanceof Controller){

 // 执行Controller适配器
}

If(hanlder instanceof  HttpControler){

 // 执行我们的HttpController

}

If(hanlder instanceof  ServletControler){

 // 执行我们的HttpController

}

If(hanlder instanceof  AnnotationControler){

 // 执行我们的AnnotationController
}

简单实现接口

@Controller("/httpRequestHandler")
public class ExtHttpRequestHandlerAdapter implements HttpRequestHandler {

    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("httpRequestHandler");
    }
}

这个时候就会执行到HttpRequestHandlerAdapter适配器

模拟SpringMVC适配器模式

HandlerAdapter

public interface HandlerAdapter {
    /**
     * 根据hanlder判断是那个HandlerAdapter类型 如果找到对应的类型话返回true
     */
    boolean supports(Object handler);
    /**
     * 执行我们的请求方法
     */
    void handle(Object handler);
}

HandlerAdapter子类

public class AnnotationHandlerAdapter implements HandlerAdapter {
    /**
     * 注解形式的适配器
     */
    public boolean supports(Object handler) {
        return (handler instanceof AnnotationController);
    }

    public void handle(Object handler) {
        ((AnnotationController) handler).hanlder();
    }
}
public class HttpRequestHandlerAdapter implements HandlerAdapter {
    /**
     * Http类型 适配器
     */
    public boolean supports(Object handler) {
        return (handler instanceof HttpController);
    }

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

Controller

public interface Controller {

    //请求方法
    void hanlder();
}

Controller子类

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

DispatcherServlet

public class DispatcherServlet {
    private List<HandlerAdapter> handlerAdapters;

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

本文参考:

蚂蚁课堂

http://www.mayikt.com/

 

 

© 著作权归作者所有

须臾之余
粉丝 125
博文 68
码字总数 178724
作品 0
吉安
程序员
私信 提问
杂谈篇之我是怎么读源码的,授之以渔

读源码的经历 刚参加工作那会,没想过去读源码,更没想过去改框架的源码;总想着别人的框架应该是完美的、万能的,应该不需要改;另外即使我改了源码,怎么样让我的改动生效了? 项目中引用的...

编程SHA
02/19
53
2
Spring框架中的设计模式(五)

Spring框架中的设计模式(五) 通过以前的4篇文章,我们看到Spring采用了大量的关于创建和结构方面的设计模式。本文将描述属于行为方面的两种设计模式:命令和访问者。 前传: Spring框架中的...

瑞查德-Jack
2018/07/20
97
0
现代Java进阶之路必备技能——2019 版

Java技术的学习阶段有三 第1个是java基础,比如对集合类,并发,IO,JVM,内存模型,泛型,异常,反射,等有深入了解。 第2个是全面的互联网技术相关知识,比如redis,mogodb,nginx,代码自...

Java小仙女
03/26
0
0
Spring中涉及的设计模式总结

Spring中涉及的设计模式总结 1.简单工厂(非23种设计模式中的一种) 实现方式:BeanFactory。 Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得Bean对象,但是否是...

caoxiaohong1005
2018/04/22
0
0
Spring框架中的设计模式(四)​

Spring框架中的设计模式(四) 本文是Spring框架中使用的设计模式第四篇。本文将在此呈现出新的3种模式。一开始,我们会讨论2种结构模式:适配器和装饰器。在第三部分和最后一部分,我们将讨...

瑞查德-Jack
2018/07/20
104
0

没有更多内容

加载失败,请刷新页面

加载更多

崛起于Springboot2.X之5分钟解决单点登陆(53)

SpringBoot2.X心法总纲 1、pom文件依赖 <dependency> <groupId>com.majiaxueyuan</groupId> <artifactId>sso-core</artifactId> <version>1.2.2</version></dependency> 2、......

木九天
6分钟前
2
0
面向对象和面向过程的区别

面向过程 优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。 缺点:没有面向对...

无名氏的程序员
7分钟前
3
0
OpenStack大事记

2010年7月19日,Rackspace、NASA、Citrix、Dell共同开发并发布OpenStack第一个版本。 2011年10月,Rackspace放弃OpenStack控制权,交由OpenStack藕色 2012年5月NASA宣布退出OpenStack的开发。...

大别阿郎
8分钟前
0
0
面向对象的简单应用—以交通工具(Vehicle)为列

请定义一个交通工具(Vehicle)的类其中有: 属性: 速度(speed)、 体积(size)等,方法:移动(move())、设置速度(setSpeed(int speed))、加速 speedUp()、减速 speedDown()等。最后在测试类 Ve...

INEVITABLE
18分钟前
2
0
通往艺术家之路

通往艺术家之路 并发编程中,开发者往往需要权衡锁的颗粒粗细,锁住的代码块太大呢会导致可能的线程堵塞,锁的颗粒太细呢又会因为频繁地加锁解锁导致系统用户态内核态的转换从而消费很多时间...

StupidZhe
19分钟前
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部