【SpringMVC】SpringMVC source code - HandlerAdapter & Adapter Design Pattern

Description

【SpringMVC】SpringMVC Source Code - Running Process

In the passage above, we looked into the source code of SpringMVC to review the running process of SpringMVC. Then we posted a question, “why does the Handler handle the request using HandlerAdapter instead of handling itself?”. I guessed it was about Adapter Design Pattern, but for compatibility instead of scalability.

Environment & Tools

IntelliJ IDEA 2018.3 (Ultimate Edition), JRE: 1.8, maven 3.6, SpringBoot 2.0.5.RELEASE,

Guide

Adapter Design Pattern

Before looking into HandlerAdapter to find out how it uses Adapter Design Pattern, let’s take a quick glance at what Adapter Design Pattern is.

适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口。adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

2019.03.21 - 01

1
2
3
4
5
6
7
public class Client {
public static void main(String[] args) {
// when we need Adaptee, we use Adapter instead of Adaptee
Target target=new Adapter();
target.request();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Target is an abstraction of Adapter, designed to lower coupling 
public class Target {
public void request() {
System.out.println("普通的请求");
}
}

// the real Adapter
public class Adapter extends Target {
private Adaptee adaptee=new Adaptee();

@Override
public void request() {
// when we use Adapter, we are actually using Adaptee
adaptee.specificRequest();
}
}

// Adaptee which is not suitable to newly situation and needs to be adapted
public class Adaptee {
public void specificRequest() {
System.out.println("特殊的请求");
}
}

HandlerAdapter

Let’s find out why and how SpringMVC uses Adapter Design Pattern in HandlerAdapter.

When it iterates List<HandlerAdapter> handlerAdapters, it has 3 handlerAdapters, including RequestMappingHandlerAdapter, HttpRequestHandlerAdapter and SimpleControllerHandlerAdapter

2019.03.21 - 02

Then it uses RequestMappingHandlerAdapter to handle the request, because the GreetingController.greeting() is annotated with @RequestMapping

2019.03.21 - 03

Apparently, DispatcherServlet is exactly the client who uses the adapter

HandlerAdapter is the Target which is an abstraction of Adapter

2019.03.21 - 04

AbstractHandlerMethodAdapter or RequestMappingHandlerAdapter is the Adapter to HandlerMethod Adaptee

2019.03.21 - 05

HttpRequestHandlerAdapter is the Adapter to HttpRequestHandler Adaptee

2019.03.21 - 06

SimpleServletHandlerAdapter is the Adapter to Servlet Adaptee

2019.03.21 - 07

SimpleControllerHandlerAdapter is the Adapter to Controller Adaptee

2019.03.21 - 08

Summary

Adapter Design Pattern: Most of time Adapter is used to encapsulate the Adaptee which is out of style or no longer convenient to use. So we define an adapter and encapsulate the complexity of using the Adaptee. So that we can use the Adaptee function by using the Adapter more conveniently.

In my opinion, HandlerAdapter in SpringMVC could be used to be compatible with Servlet.

Reference

《大话设计模式–适配器模式》笔记

看springmvc适配器模式—HandlerAdapter

springMVC源码分析–HandlerAdapter(一)

springMVC源码分析–SimpleServletHandlerAdapter(二)

springMVC源码分析–SimpleControllerHandlerAdapter(三)

springMVC源码分析–HttpRequestHandlerAdapter(四)

使用IntelliJ IDEA查看类的继承关系图形

Intellij IDEA 查找接口实现类的快捷键

Q&A

Q: The structure of Adapter Design Pattern is quite similar to that of Proxy Design Pattern, so what is the difference between them?

A: In Adapter Design Pattern, we only invoke the Adaptee. But in Proxy Design Pattern, we will do some thing else before or after we invoke the proxied subject.