一、适配器模式在 SpringMVC 框架应用的源码分析

  1、SpringMVC 中的 HandlerAdapter,就使用了适配器模式;

  2、SpringMVC 处理请求的流程回顾:

                     

 

  3、使用 HandlerAdapter 的原因分析:

    在容器中会有多个处理器(Controller),且它们类型不同,有多重实现方式,那么调用方式就不是确定的。如果需要直接调用 Controller 方法,需要调用的时候就得不断是使用 if else 来进行判断是哪一种子类然后执行。如果后面要扩展 Controller,就得修改原来的代码,违背了 OCP 原则。

    不适用设计模式情况下:

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

 

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

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

二、适配器模式在 SpringMVC 框架应用的源码剖析

  1、流程图

    

 

 

 

  2、源码分析

    (1)DispatcherServlet 中 doDispatch 方法

 1 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
 2         HttpServletRequest processedRequest = request;
 3         HandlerExecutionChain mappedHandler = null;
 4         boolean multipartRequestParsed = false;
 5         WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
 6 
 7         try {
 8             try {
 9                 ModelAndView mv = null;
10                 Object dispatchException = null;
11 
12                 try {
13                     processedRequest = this.checkMultipart(request);
14                     multipartRequestParsed = processedRequest != request;
15                     mappedHandler = this.getHandler(processedRequest); //根据请求获取对应的处理器(controller)
16                     if (mappedHandler == null) {
17                         this.noHandlerFound(processedRequest, response);
18                         return;
19                     }
20 
21                     HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());//根据controller获取对应adapter
22                     String method = request.getMethod();
23                     boolean isGet = "GET".equals(method);
24                     if (isGet || "HEAD".equals(method)) {
25                         long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
26                         if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
27                             return;
28                         }
29                     }
30 
31                     if (!mappedHandler.applyPreHandle(processedRequest, response)) {
32                         return;
33                     }
34 
35                     mv = ha.handle(processedRequest, response, mappedHandler.getHandler());//根据Adapter执行对应controller里面的方法,返回ModelAndView
36                     if (asyncManager.isConcurrentHandlingStarted()) {
37                         return;
38                     }
39 
40                     this.applyDefaultViewName(processedRequest, mv);
41                     mappedHandler.applyPostHandle(processedRequest, response, mv);
42                 } catch (Exception var20) {
43                     dispatchException = var20;
44                 } catch (Throwable var21) {
45                     dispatchException = new NestedServletException("Handler dispatch failed", var21);
46                 }
47 
48                 this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
49             } catch (Exception var22) {
50                 this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
51             } catch (Throwable var23) {
52                 this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
53             }
54 
55         } finally {
56             if (asyncManager.isConcurrentHandlingStarted()) {
57                 if (mappedHandler != null) {
58                     mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
59                 }
60             } else if (multipartRequestParsed) {
61                 this.cleanupMultipart(processedRequest);
62             }
63 
64         }
65     }

 

  

  (2)getHandler 方法

 1  @Nullable
 2     protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
 3         if (this.handlerMappings != null) {
 4             Iterator var2 = this.handlerMappings.iterator();
 5 
 6             while(var2.hasNext()) {
 7                 HandlerMapping mapping = (HandlerMapping)var2.next();
 8                 HandlerExecutionChain handler = mapping.getHandler(request);
 9                 if (handler != null) {
10                     return handler;
11                 }
12             }
13         }
14 
15         return null;
16     }

 

  (3)getHandlerAdapter 方法:遍历所有的Adapter,根据 controller获取对应 Adapter

 1 protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
 2         if (this.handlerAdapters != null) {
 3             Iterator var2 = this.handlerAdapters.iterator();
 4 
 5             while(var2.hasNext()) {
 6                 HandlerAdapter adapter = (HandlerAdapter)var2.next();
 7                 if (adapter.supports(handler)) {
 8                     return adapter;
 9                 }
10             }
11         }
12 
13         throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
14     }

 

  (4)以 HttpRequestHandlerAdapter 为例:

 1 public class HttpRequestHandlerAdapter implements HandlerAdapter {
 2     public HttpRequestHandlerAdapter() {
 3     }
 4 
 5     public boolean supports(Object handler) {
 6         return handler instanceof HttpRequestHandler;
 7     }
 8 
 9     @Nullable
10     public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
11         ((HttpRequestHandler)handler).handleRequest(request, response);
12         return null;
13     }
14 
15     public long getLastModified(HttpServletRequest request, Object handler) {
16         return handler instanceof LastModified ? ((LastModified)handler).getLastModified(request) : -1L;
17     }
18 }

 

 

 

三、手动代码实现

  实现一套代码来模拟springMVC

  Controller 类:

 1 /**
 2  * 多种Controller实现 
 3  */ 
 4 public interface Controller {
 5 
 6 }
 7 
 8 class HttpController implements Controller {
 9     public void doHttpHandler() {
10         System.out.println("http...");
11     }
12 }
13 
14 class SimpleController implements Controller {
15     public void doSimplerHandler() {
16         System.out.println("simple...");
17     }
18 }
19 
20 class AnnotationController implements Controller {
21     public void doAnnotationHandler() {
22         System.out.println("annotation...");
23     }
24 }

 

  

  Adapter 接口及实现:

 

 1 /**
 2  * 定义一个Adapter接口
 3  */
 4 public interface HandlerAdapter {
 5     public boolean supports(Object handler);
 6 
 7     public void handle(Object handler);
 8 }
 9 
10 /**
11  * 多种适配器类
12  */
13 class SimpleHandlerAdapter implements HandlerAdapter {
14 
15     @Override
16     public void handle(Object handler) {
17         ((SimpleController) handler).doSimplerHandler();
18     }
19 
20     @Override
21     public boolean supports(Object handler) {
22         return (handler instanceof SimpleController);
23     }
24 
25 }
26 
27 class HttpHandlerAdapter implements HandlerAdapter {
28 
29     @Override
30     public void handle(Object handler) {
31         ((HttpController) handler).doHttpHandler();
32     }
33 
34     @Override
35     public boolean supports(Object handler) {
36         return (handler instanceof HttpController);
37     }
38 
39 }
40 
41 class AnnotationHandlerAdapter implements HandlerAdapter {
42 
43     @Override
44     public void handle(Object handler) {
45         ((AnnotationController) handler).doAnnotationHandler();
46     }
47 
48     @Override
49     public boolean supports(Object handler) {
50 
51         return (handler instanceof AnnotationController);
52     }
53 
54 }

 

 

 

 

  测试类:模拟 DispatcherServlet

 1 public class DispatchServlet {
 2 
 3     public static List<HandlerAdapter> handlerAdapters = new ArrayList<>();
 4 
 5     public DispatchServlet() {
 6         handlerAdapters.add(new AnnotationHandlerAdapter());
 7         handlerAdapters.add(new HttpHandlerAdapter());
 8         handlerAdapters.add(new SimpleHandlerAdapter());
 9     }
10 
11     public void doDispatch() {
12 
13         // 此处模拟SpringMVC从request取handler的对象,
14         // 适配器可以获取到希望的Controller
15          HttpController controller = new HttpController();
16         // AnnotationController controller = new AnnotationController();
17         //SimpleController controller = new SimpleController();
18         // 得到对应适配器
19         HandlerAdapter adapter = getHandler(controller);
20         // 通过适配器执行对应的controller对应方法
21         adapter.handle(controller);
22 
23     }
24 
25     public HandlerAdapter getHandler(Controller controller) {
26         //遍历:根据得到的controller(handler), 返回对应适配器
27         for (HandlerAdapter adapter : handlerAdapters) {
28             if (adapter.supports(controller)) {
29                 return adapter;
30             }
31         }
32         return null;
33     }
34 
35     public static void main(String[] args) {
36         new DispatchServlet().doDispatch();
37     }
38 
39 }

   说明:

    1)Spring 定义了一个适配接口,使得每一种 conroller 有一种对应的适配器实现类;

    2)适配器代替 controller 执行相应的方法;

    3)扩展 controller 时,只需要增加一个适配器类就完成了 SpringMVC 的扩展;

  

 

posted on 2021-01-17 18:42  格物致知_Tony  阅读(390)  评论(0编辑  收藏  举报

目录导航