前言     关于SpringMVC初始化ContextLoader中的XMLWebApplicationContext,以及DispatcherServlet初始化等等,这样的原理 已经有N多的前辈和牛人总结过了, 我就不在这里重复轮子了。~ 
    正文     找到DispatcherServlet类中的doDispatch体,我们可以看到,它的作用是相当于在Servlet的 doService调用的。 也就是用来传递request给我们编写的Controller并执行相应的方法、返回ModeView对象。
     执行的代码片段:

...
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
...

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

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

Java代码

springmvc适配器 干的啥事情_springmvc适配器 干的啥事情

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代码

springmvc适配器 干的啥事情_springmvc适配器 干的啥事情_02

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. "http...");  
15.     }  
16. }  
17.   
18. public class SimpleController implements Controller{  
19. public void doSimplerHandler(){  
20. "simple...");  
21.     }  
22. }  
23.   
24. public class AnnotationController implements Controller{  
25. public void doAnnotationHandler(){  
26. "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. new AnnotationHandlerAdapter());  
86. new HttpHandlerAdapter());  
87. 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. 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.       
118.