一、适配器模式在 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 的扩展;