适配器模式(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. 简单的dos命令

    cd ..   进入上一层目录cd /..   进入当前盘所有根目录d:  进入d盘dir  查看下一级目录d:>d:\abc.txt 新建一个文档hostname   主机名SET 查看环境变 ...

  2. 防止XSS攻击的方式

    主要有三种请求方式,进行过滤替换非法符号 1.普通的GET请求数据: 2.FORM表单提交数据: 3.Json格式数据提交: 把下面5个文件放入项目中即可 package com.joppay.adm ...

  3. linux ssh认证(公钥机)配置

    一.产生背景 在实际工作中,linux集群需要自动化的管理,市面上较常见的自动化运维工具诸如ansible,puppet,saltstack:轻量级的有pssh系列,这其中大多数工具使用的前提就是集群 ...

  4. 51 Nod 1091 线段的重叠

    2017-09-24 19:51:41 writer:pprp 上一个题目就是关于线段重叠最大值,这个是找区间最长重合? 给你n个线段,然后让你在其中选择两条,使两条尽可能重合多一点 解决方法; 1. ...

  5. Maven 一段时间知识小结2

    父 Pom.xml <parent> <groupId>org.springframework.boot</groupId> <artifactId>s ...

  6. awk字符串处理

    awk 字符串处理函数 awk提供了许多强大的字符串函数,见下表:awk内置字符串函数gsub(r,s)    在整个$0中用s替代rgsub(r,s,t)    在整个t中用s替代rindex(s, ...

  7. 【平台中间件】Nginx安装配置,实现版本更新不影响服务访问

    为什么要做负载均衡? 当你网站是一个企业站.个人博客的时候,或者访问量比较小的时候,一台服务器完全应付的了,那就完全没必要做负载均衡.但是,如果你的网站是平台级别,用户达到十万百万级别了,一台服务器明 ...

  8. unity3D用什么语言开发好?

    unity3D用什么语言开发好? 一.总结 一句话总结:选c# 同时U3D团队也会把支持的重心转移到C#,也就是说文档和示例以及社区支持的重心都在C#,C#的文档会是最完善的,C#的代码实例会是最详细 ...

  9. vs2012 在调试或运行的过程中不能加断点

    在使用VS2012 的过程中,突然发现在调试的过程中,不能加断点,显示断点未能绑定.在搜寻了很多解决方案后未能解决,3.23这一天,重装了VS也没有用. 便想着把网上所有的方法都试个遍也要解决这个问题 ...

  10. webBrowser.DocumentText重新赋值无效解决方法

    因为webBrowser这个控件的webBrowser.DocumentText是异步的,所以要自己调用刷新: webBrowser.Navigate("about:blank") ...