• 适配器模式之SpringMvc源码HandlerAdapter


    适配器模式之SpringMvc源码HandlerAdapter

    • 适配器模式可以分为继承适配器和组合适配器, HandlerAdapter是一种组合适配器模式, Handler作为组合在HandlerAdapter中

    • HandlerAdapter作为一个适配器, 适配Handler, 这里的Handler都用Object代替, 在具体根据instance of 类型去判断是哪一种Handler

    • 常见的Handler有Server, Controller , HttpRequestHandler

    • 这些Handler的实现方法的方法名都不一样, 但是我们要让使用者通过统一的方法去调用, 不去理会里面的差异, 所以就有了适配器

    • 我们看一下Server, Controller , HttpRequestHandler的具体会调用到的代码, 会发现他们连基本的方法名都不一样, 所以无法通过统一的接口调用, 要用到适配器

      • javax.servlet.Servlet#service
      • org.springframework.web.servlet.mvc.Controller#handleRequest
      • org.springframework.web.HttpRequestHandler#handleRequest
    • 再来看一下实现了适配器HandlerAdapter的具体适配器SimpleServletHandlerAdapter, SimpleControllerHandlerAdapter, HttpRequestHandlerAdapter

      • public class SimpleServletHandlerAdapter implements HandlerAdapter {
        
        	@Override
        	public boolean supports(Object handler) {
        		return (handler instanceof Servlet);
        	}
        
        	@Override
        	@Nullable
        	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
        			throws Exception {
        
        		((Servlet) handler).service(request, response);
        		return null;
        	}
        
        ...
        
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
      • public class SimpleControllerHandlerAdapter implements HandlerAdapter {
        
        	@Override
        	public boolean supports(Object handler) {
        		return (handler instanceof Controller);
        	}
        
        	@Override
        	@Nullable
        	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
        			throws Exception {
        
        		return ((Controller) handler).handleRequest(request, response);
        	}
        
        ...
        
        }
        
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
      • public class HttpRequestHandlerAdapter implements HandlerAdapter {
        
        	@Override
        	public boolean supports(Object handler) {
        		return (handler instanceof HttpRequestHandler);
        	}
        
        	@Override
        	@Nullable
        	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
        			throws Exception {
        
        		((HttpRequestHandler) handler).handleRequest(request, response);
        		return null;
        	}
        
        .....
        
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
    • 在这里插入图片描述

    • 这里可能你已经明白了, 这个适配器向外暴露了统一的handle((HttpServletRequest request, HttpServletResponse response, Object handler)方法, 那样就可以统一调用了。 大功告成。 完结撒花, 如果你还想看下DispatcherServlet, 那么我带你继续往下看看, 嘻嘻。

    • DispatcherServlet中的方法doDispatch如下, 重点看一下getHandlerAdapter, 这个就是适配器模式挑选出来的具体是哪一个适配器合适, 然后mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); 这个都统一调用handle方法, 这样就适配和不同hadler之间的差异了, 好了, 散会!

      • 	protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        		HttpServletRequest processedRequest = request;
        		HandlerExecutionChain mappedHandler = null;
        		....
                    ....
        				// Determine handler for the current request.
        				mappedHandler = getHandler(processedRequest);
        				....
                            ...
        				// Determine handler adapter for the current request.
        				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
        
        				...
                            ...
        				// Actually invoke the handler.
        				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
        
        				.....
                            .....
        			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        		}
        		
        	}
        
        	protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
        		if (this.handlerAdapters != null) {
        			for (HandlerAdapter ha : this.handlerAdapters) {
        				if (logger.isTraceEnabled()) {
        					logger.trace("Testing handler adapter [" + ha + "]");
        				}
                        // 这个就是适配器模式挑选出来的具体是哪一个适配器合适
        				if (ha.supports(handler)) {
        					return ha;
        				}
        			}
        		}
        		throw new ServletException("No adapter for handler [" + handler +
        				"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
        	}
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
        • 34
        • 35
        • 36
        • 37
        • 38
        • 39
  • 相关阅读:
    如果报华为网络工程师中级培训班一般学费多少?
    RT-Thread基于STM32H743的网络通信调试
    Word文档怎样翻译?Word文档翻译方法大分享
    G1垃圾回收器在并发场景调优
    本地的git仓库和远程仓库
    【收纳】电脑资料-高效整理电脑上的文件
    基于AM335X开发板 ARM Cortex-A8——Acontis EtherCAT主站开发案例
    VRP基础及操作
    实现一个快速排序算法,并分析算法的时间复杂度。
    风雨秋招路-CV太难了-记得复盘
  • 原文地址:https://blog.csdn.net/biubiubiubibibi/article/details/126698764