zoukankan      html  css  js  c++  java
  • springmvc适配器的应用

         前言     关于SpringMVC初始化ContextLoader中的XMLWebApplicationContext,以及DispatcherServlet初始化等等,这样的原理 已经有N多的前辈和牛人总结过了, 我就不在这里重复轮子了。~ 
        正文     找到DispatcherServlet类中的doDispatch体,我们可以看到,它的作用是相当于在Servlet的 doService调用的。 也就是用来传递request给我们编写的Controller并执行相应的方法、返回ModeView对象。
         执行的代码片段:
    1. ...  
    2. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());  
    3. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
    4. ...  
    ...
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    ...
    
    mappedHandler.getHandler()得到的是Controller对象 而此处并非采用直接 调用.handlerRequest或者MultiActionController中编写的自定义方法,而采用了一个HandlerAdapter 的接口。
    此处采用了适配器模式, 由于Controller的类型不同,有多重实现方式,那么调用方式就不是确定的,如果需要直接调用Controller方法,需要在代码中写成如下形式:
    Java代码 复制代码 收藏代码
    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. ...  
    if(mappedHandler.getHandler() instanceof MultiActionController){
       ((MultiActionController)mappedHandler.getHandler()).xxx
    }else if(mappedHandler.getHandler() instanceof XXX){
        ...
    }else if(...){
       ...
    }
    ...
    
    这样假设如果我们增加一个HardController,就要在代码中加入一行 if(mappedHandler.getHandler() instanceof  HardController) 这种形式就使得程序难以维护,也违反了设计模式中的开闭原则 --  对扩展开放,对修改关闭。
    因此Spring定义了一个适配接口,使得每一种Controller有一种对应的适配器实现类, 让适配器代替controller执行相应的方法。这样在扩展Controller 时,只需要增加一个适配器类就完成了SpringMVC的扩展了,真的是很精巧的做法!
    废话不多说还是上代码吧,为了看得清楚,就自己实现一套代码来模拟springMVC, 直接贴Spring源码容易降低关注点。
    Java代码 复制代码 收藏代码
    1. //定义一个Adapter接口  
    2. public interface HandlerAdapter {  
    3.     public boolean supports(Object handler);  
    4.     public void handle(Object handler);  
    5. }  
    6.   
    7. //以下是三种Controller实现  
    8. public interface Controller {  
    9.   
    10. }  
    11.   
    12. public class HttpController implements Controller{  
    13.     public void doHttpHandler(){  
    14.         System.out.println("http...");  
    15.     }  
    16. }  
    17.   
    18. public class SimpleController implements Controller{  
    19.     public void doSimplerHandler(){  
    20.         System.out.println("simple...");  
    21.     }  
    22. }  
    23.   
    24. public class AnnotationController implements Controller{  
    25.     public void doAnnotationHandler(){  
    26.         System.out.println("annotation...");  
    27.     }  
    28. }  
    29.   
    30.   
    31. //下面编写适配器类  
    32.   
    33. public class SimpleHandlerAdapter implements HandlerAdapter {  
    34.   
    35.   
    36.     public void handle(Object handler) {  
    37.         ((SimpleController)handler).doSimplerHandler();  
    38.     }  
    39.   
    40.     public boolean supports(Object handler) {  
    41.         return (handler instanceof SimpleController);  
    42.     }  
    43.   
    44. }  
    45.   
    46.   
    47. public class HttpHandlerAdapter implements HandlerAdapter {  
    48.   
    49.     public void handle(Object handler) {  
    50.         ((HttpController)handler).doHttpHandler();  
    51.     }  
    52.   
    53.     public boolean supports(Object handler) {  
    54.         return (handler instanceof HttpController);  
    55.     }  
    56.   
    57. }  
    58.   
    59.   
    60.   
    61. public class AnnotationHandlerAdapter implements HandlerAdapter {  
    62.   
    63.     public void handle(Object handler) {  
    64.         ((AnnotationController)handler).doAnnotationHandler();  
    65.     }  
    66.   
    67.     public boolean supports(Object handler) {  
    68.           
    69.         return (handler instanceof AnnotationController);  
    70.     }  
    71.   
    72. }  
    73.   
    74.   
    75. //模拟一个DispatcherServlet  
    76. import java.util.ArrayList;  
    77. import java.util.List;  
    78.   
    79.   
    80. public class DispatchServlet {  
    81.       
    82.     public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();   
    83.       
    84.     public DispatchServlet(){  
    85.         handlerAdapters.add(new AnnotationHandlerAdapter());  
    86.         handlerAdapters.add(new HttpHandlerAdapter());  
    87.         handlerAdapters.add(new SimpleHandlerAdapter());  
    88.     }  
    89.       
    90.       
    91.     public void doDispatch(){  
    92.           
    93.         //此处模拟SpringMVC从request取handler的对象,仅仅new出,可以出,               
    94.                      //不论实现何种Controller,适配器总能经过适配以后得到想要的结果  
    95. //      HttpController controller = new HttpController();  
    96. //      AnnotationController controller = new AnnotationController();  
    97.         SimpleController controller = new SimpleController();  
    98.         //得到对应适配器  
    99.         HandlerAdapter adapter = getHandler(controller);  
    100.         //通过适配器执行对应的controller对应方法  
    101.         adapter.handle(controller);  
    102.           
    103.     }  
    104.       
    105.     public HandlerAdapter getHandler(Controller controller){  
    106.         for(HandlerAdapter adapter: this.handlerAdapters){  
    107.             if(adapter.supports(controller)){  
    108.                 return adapter;  
    109.             }  
    110.         }  
    111.         return null;  
    112.     }  
    113.       
    114.     public static void main(String[] args){  
    115.         new DispatchServlet().doDispatch();  
    116.     }  
    117.       
  • 相关阅读:
    [图形学] 结束 [Unity Shader] 开始
    [图形学] Chp18 OpenGL表面纹理函数
    [图形学] Chp17 OpenGL光照和表面绘制函数
    [图形学] Chp14 GLU曲面裁剪函数程序示例及样条表示遗留问题
    [图形学] Chp10 OpenGL三维观察程序示例
    [图形学] 问题: 裁剪窗口坐标对应显示窗口中像素是一对一还是一对多?
    [图形学] Chp9 三维几何变换--栈处理函数与矩阵管理函数的区别
    [图形学] 习题8.12 NLN二维线段裁剪算法实现
    [图形学] 习题8.6 线段旋转后使用Cohen-Sutherland算法裁剪
    [图形学] Chp8 使用双缓存创建帧动画
  • 原文地址:https://www.cnblogs.com/lulu638/p/4474698.html
Copyright © 2011-2022 走看看