适配器模式之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; } ... }
-
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); } ... }
-
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; } ..... }
-
-
这里可能你已经明白了, 这个适配器向外暴露了统一的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"); }
-