适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作

适用场景:

1、已经存在的类的接口不符合我们的需求;

2、创建一个可以复用的类,使得该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作;

3、在不对每一个都进行子类化以匹配它们的接口的情况下,使用一些已经存在的子类。

找到DispatcherServlet类中的doDispatch体,我们可以看到,它的作用是相当于在Servlet的 doService调用的。 也就是用来传递request给我们编写的Controller并执行相应的方法、返回ModeView对象。

执行的代码片段:

  1. ...
  2. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
  3. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
  4. ...

mappedHandler.getHandler()得到的是Controller对象 
而此处并非采用直接 调用.handlerRequest或者MultiActionController中编写的自定义方法,而采用了一个HandlerAdapter 的接口。

此处采用了适配器模式, 由于Controller的类型不同,有多重实现方式,那么调用方式就不是确定的,如果需要直接调用Controller方法,需要在代码中写成如下形式:

  1. if(mappedHandler.getHandler() instanceof MultiActionController){
  2. ((MultiActionController)mappedHandler.getHandler()).xxx
  3. }else if(mappedHandler.getHandler() instanceof XXX){
  4. ...
  5. }else if(...){
  6. ...
  7. }
  8. ...

这样假设如果我们增加一个HardController,就要在代码中加入一行 if(mappedHandler.getHandler() instanceof  HardController) 
这种形式就使得程序难以维护,也违反了设计模式中的开闭原则 --  对扩展开放,对修改关闭。

因此Spring定义了一个适配接口,使得每一种Controller有一种对应的适配器实现类, 
让适配器代替controller执行相应的方法。这样在扩展Controller 时,只需要增加一个适配器类就完成了SpringMVC的扩展了,真的是很精巧的做法!

废话不多说还是上代码吧,为了看得清楚,就自己实现一套代码来模拟springMVC, 直接贴Spring源码容易降低关注点。

    1. //定义一个Adapter接口
    2. public interface HandlerAdapter {
    3. public boolean supports(Object handler);
    4. public void handle(Object handler);
    5. }
    6. //以下是三种Controller实现
    7. public interface Controller {
    8. }
    9. public class HttpController implements Controller{
    10. public void doHttpHandler(){
    11. System.out.println("http...");
    12. }
    13. }
    14. public class SimpleController implements Controller{
    15. public void doSimplerHandler(){
    16. System.out.println("simple...");
    17. }
    18. }
    19. public class AnnotationController implements Controller{
    20. public void doAnnotationHandler(){
    21. System.out.println("annotation...");
    22. }
    23. }
    24. //下面编写适配器类
    25. public class SimpleHandlerAdapter implements HandlerAdapter {
    26. public void handle(Object handler) {
    27. ((SimpleController)handler).doSimplerHandler();
    28. }
    29. public boolean supports(Object handler) {
    30. return (handler instanceof SimpleController);
    31. }
    32. }
    33. public class HttpHandlerAdapter implements HandlerAdapter {
    34. public void handle(Object handler) {
    35. ((HttpController)handler).doHttpHandler();
    36. }
    37. public boolean supports(Object handler) {
    38. return (handler instanceof HttpController);
    39. }
    40. }
    41. public class AnnotationHandlerAdapter implements HandlerAdapter {
    42. public void handle(Object handler) {
    43. ((AnnotationController)handler).doAnnotationHandler();
    44. }
    45. public boolean supports(Object handler) {
    46. return (handler instanceof AnnotationController);
    47. }
    48. }
    49. //模拟一个DispatcherServlet
    50. import java.util.ArrayList;
    51. import java.util.List;
    52. public class DispatchServlet {
    53. public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();
    54. public DispatchServlet(){
    55. handlerAdapters.add(new AnnotationHandlerAdapter());
    56. handlerAdapters.add(new HttpHandlerAdapter());
    57. handlerAdapters.add(new SimpleHandlerAdapter());
    58. }
    59. public void doDispatch(){
    60. //此处模拟SpringMVC从request取handler的对象,仅仅new出,可以出,
    61. //不论实现何种Controller,适配器总能经过适配以后得到想要的结果
    62. //      HttpController controller = new HttpController();
    63. //      AnnotationController controller = new AnnotationController();
    64. SimpleController controller = new SimpleController();
    65. //得到对应适配器
    66. HandlerAdapter adapter = getHandler(controller);
    67. //通过适配器执行对应的controller对应方法
    68. adapter.handle(controller);
    69. }
    70. public HandlerAdapter getHandler(Controller controller){
    71. for(HandlerAdapter adapter: this.handlerAdapters){
    72. if(adapter.supports(controller)){
    73. return adapter;
    74. }
    75. }
    76. return null;
    77. }
    78. public static void main(String[] args){
    79. new DispatchServlet().doDispatch();
    80. }
    81. }

SpringMVC中的适配器的更多相关文章

  1. SpringMVC中的适配器(适配者模式)

    此处采用了适配器模式, 由于Controller的类型不同,有多重实现方式,那么调用方式就不是确定的,如果需要直接调用Controller方法,需要在代码中写成如下形式: if(mappedHandl ...

  2. SpringMVC中注解和非注解方式下的映射器和适配器总结

    1. 非注解方式 1.1 处理器适配器 上一节中使用的处理器适配器是:org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapte ...

  3. 【SpringMVC学习03】SpringMVC中注解和非注解方式下的映射器和适配器总结

    从上一篇的springmvc入门中已经看到,springmvc.xml中的配置了映射器和适配器,是使用非注解的方式来配置的,这是非注解方式的一种,这里再复习一下: 1. 非注解方式 1.1 处理器适配 ...

  4. springmvc中RequestMapping的解析

    在研究源码的时候,我们应该从最高层来看,所以我们先看这个接口的定义: package org.springframework.web.servlet; import javax.servlet.htt ...

  5. springMVC中ajax的使用

    springMVC中使用ajax有两种方法,第一种是根据servletAPI来使用ajax,第二种是根据springMVC给我们提供的API来使用. 一.根据servletAPI: springMVC ...

  6. JavaEE开发之SpringMVC中的自定义拦截器及异常处理

    上篇博客我们聊了<JavaEE开发之SpringMVC中的路由配置及参数传递详解>,本篇博客我们就聊一下自定义拦截器的实现.以及使用ModelAndView对象将Controller的值加 ...

  7. 将SpringMVC中的HttpMessageConverter替换为Gson

    读者们看到这个标题也许会感到奇怪,SpringMVC中默认的HttpMessageConverter不是Jackson吗,但是我在使用的过程中发现Jackson并不好用,如果有一些复杂的嵌套类型,当然 ...

  8. 关于springMVC中component-scan的问题以及springmvc.xml整理

    关于springMVC中component-scan的问题以及springmvc.xml整理 一.component-scan问题和解决办法         最近在学习使用springMVC+myba ...

  9. 【SpringMVC学习06】SpringMVC中的数据校验

    这一篇博文主要总结一下springmvc中对数据的校验.在实际中,通常使用较多是前端的校验,比如页面中js校验,对于安全要求较高的建议在服务端也要进行校验.服务端校验可以是在控制层conroller, ...

随机推荐

  1. nginx windows版本 1024限制

    Windows版本因为文件访问句柄数被限制为1024了,当访问量大时就会无法响应. 会有如下错误提示:maximum number of descriptors supported by select ...

  2. hadoop yarn HA集群搭建

    可先完成hadoop namenode HA的搭建:http://www.cnblogs.com/kisf/p/7458519.html 搭建yarnde HA只需要在namenode HA配置基础上 ...

  3. HelloWorld程序编写调试及错误解决

    HelloWorld程序编写调试及错误解决 eclipse软件编写 相较于windows内置记事本,eclipse编写程序更为简单快捷.由其生成的程序模板编写如下: package helloworl ...

  4. Job流程:提交MR-Job过程

    1.一个标准 MR-Job 的执行入口: //参数 true 表示检查并打印 Job 和 Task 的运行状况 System.exit(job.waitForCompletion(true) ? 0 ...

  5. vSphere SDK for Java - 从模板部署虚拟机并配置IP地址

    vSphere for Java类库:vijava    虚拟机配置类 package com.vmware.vcenter_event.VirtualMachine; import com.vmwa ...

  6. Docker pull网络错误

    [root@Oracle ~]# docker search centos Error response from daemon: Get https://index.docker.io/v1/sea ...

  7. mybatis映射文件_select_resultMap

    实体类: Employee.java类: package com.hand.mybatis.bean; public class Employee {        private Integer e ...

  8. mac下搭建基于vue-cli 3.0的Element UI 项目

    1.安装yarn管理工具(包含node.js); 2.安装全局vue-cli全家桶: yarn global add @vue/cli 3.创建.测试一个vue-cli项目: vue create a ...

  9. nagios配置邮件报警

    1.配置sendmail vi /etc/mail.rc 加入以下行 set bsdcompat set from=邮件用户名@domain.com smtp=smtp.126.com set smt ...

  10. java自带的MD5

    前言:        MD5可生成16.32.64位数的签名. // MD5加码,32位 public static String toMD5(String plainText) { String r ...