前言     关于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方法,需要在代码中写成如下形式:

  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源码容易降低关注点。

  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. }

springmvc适配器的应用的更多相关文章

  1. SpringMVC的映射器,适配器,控制器

    一.各司其职   (1)HandlerMapping映射器 根据客户端请求的url,找到处理本次请求的处理器,即将请求的路径和controller关联起来 (2)HandlerAdapter适配器 对 ...

  2. JAVA基础—适配器设计模式

    适配器概念 在计算机编程中,适配器模式将一个类的接口适配成用户所期待的.使用适配器,可以使接口不兼容而无法在一起工作的类协调工作,做法是将类自己包裹在一个已经存在的类中. JDK对适配器设计模式的应用 ...

  3. SpringMVC框架三:参数绑定

    这篇文章整合了SpringMVC和MyBatis: https://www.cnblogs.com/xuyiqing/p/9419144.html 接下来看看参数绑定: 默认Conrtroller可以 ...

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

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

  5. SpringMVC的映射器、适配器、解析器

    1.处理器和适配器 1.1springmvc的映射器 根据客户端请求的url,找到处理本次请求的handler(处理器),将url和controller关联起来 1.2springmvc的适配器 对映 ...

  6. SpringMVC源码情操陶冶-HandlerAdapter适配器简析

    springmvc中对业务的具体处理是通过HandlerAdapter适配器操作的 HandlerAdapter接口方法 列表如下 /** * Given a handler instance, re ...

  7. SpringMVC源码情操陶冶-RequestMappingHandlerAdapter适配器

    承接前文SpringMVC源码情操陶冶-HandlerAdapter适配器简析.RequestMappingHandlerAdapter适配器组件是专门处理RequestMappingHandlerM ...

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

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

  9. springMVC控制器,处理器,映射器,适配器

    前端控制器DispatcherServlet <!--定义spring mvc 的前端控制器Servlet --><servlet> <!--Servlet的名称--&g ...

随机推荐

  1. hasOne

    public boolean hasOne(int n) { int lastdigit=0; while( n >0 ){ lastdigit=(n % 10); if(lastdigit== ...

  2. 20、AngularJs知识点总结 part-2

    1.作用域 当你在angularJs中创建控制器时,可以将$scope对象作为一个参数进行传递: scope 是一个 JavaScript 对象,带有属性和方法,这些属性和方法可以在视图和控制器中使用 ...

  3. 【Pascal's Triangle】cpp

    题目: Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5,R ...

  4. badboy录制提示当前页面的脚本发生错误

    利用badboy录制时,发生了错误: 网上查了查,说badboy默认使用IE浏览器,打开Internet选项—>高级,图中的两个选项不要勾选即可 然鹅,然鹅,并没有作用... 请教了好心的同行, ...

  5. 团队项目-第二次Scrum 会议

    时间:10.24 时长:30分钟 地点:线上 工作情况 团队成员 已完成任务 待完成任务 解小锐 学习官方样例 根据初步讨论结果编写初步的api文档 陈鑫 学习cocos creator基本使用 采用 ...

  6. jQuery基础知识点(上)

    jQuery是一个优秀的.轻量级的js库 ,它兼容CSS3,还兼容各种浏览器(IE 6.0+, FF1.5+, Safari 2.0+, Opera 9.0+),而jQuery2.0及后续版本将不再支 ...

  7. hdu 1846 Brave Game (博弈)

    Brave Game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. [poj] 3422 Kaka's Matrix Travels || 最小费用最大流

    原题 给一个N*N的方阵,从[1,1]到[n,n]走K次,走过每个方格加上上面的数,然后这个格上面的数变为0.求可取得的最大的值. 要求最大值,所以把边权全为负跑最小费用即可.因为只有第一次经过该点的 ...

  9. P4397 [JLOI2014]聪明的燕姿

    P4397 [JLOI2014]聪明的燕姿 题目背景 阴天傍晚车窗外 未来有一个人在等待 向左向右向前看 爱要拐几个弯才来 我遇见谁会有怎样的对白 我等的人他在多远的未来 我听见风来自地铁和人海 我排 ...

  10. android工程下assets与raw文件夹

    在应用的开发中,当我们创建一个新的Android工程后,我们会发现工程中包含了一个目录assets,另外当我们察看一些示例工程的时候,有时会发现在该工程的资源目录下会有一个raw目录(res/raw) ...