欢迎来到啾啾的博客🐱。
记录学习点滴。分享工作思考和实用技巧,偶尔也分享一些杂谈💬。
欢迎评论交流,感谢您的阅读😄。
适配器模式
适配器模式(Adapter Pattern)是将一个类的接口转换成客户希望的另一种接口。从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
一般包含目标角色(Target)、源角色(Adaptee)、适配器角色(Adapter)。
通过继承或关联的方式,由适配器将源角色转换成目标角色。
Spring MVC的适配器模式
在Spring MVC中,当一个请求到达DispatcherServlet后,DispatcherServlet需要找到一个合适的处理器Handler来处理这个请求。
这个处理器可以有多种形式,如@Controller注解类中的方法:
@Controller
public class UserController {
@GetMapping("/users/{id}")
public String getUser(@PathVariable String id, Model model) {
// ... 逻辑 ...
return "userView";
}
}
这里的 getUser 方法就是一个 Handler。
还有实现了HttpRequestHandler 接口的类:
public class MyHttpRequestHandler implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// ... 逻辑 ...
response.getWriter().write("Hello from HttpRequestHandler!");
}
}
DispatcherServlet希望以统一的方式调用各种类型的 Handler。
DispatcherServlet 本身并不直接知道如何调用 UserController 类的 getUser 方法,或者 MyHttpRequestHandler 类的 handleRequest 方法。这些 Handler 的调用方式、参数解析、返回值处理都千差万别。
这个时候,适配器登场了。Spring MVC定义了一个用户DispatcherServlet期望的目标角色HandlerAdapter接口,HandlerAdapter接口定义了一个DispatcherServlet可以统一调用的标准方法,handle()方法。
被适配的源角色就是上面提到的类型不同的Handler。
但是当我们去翻看源码时,我们发现了一件事情,Spring不止有一个适配器角色。如下:
这是因为Spring提供了多种HandlerAdapter的实现,每种实现负责适配一种或一类特定的Handler。
RequestMappingHandlerAdapter处理的适配对象为:被@RequestMapping、@GetMapping注解的控制器方法。
HttpRequestHandlerAdapter处理的适配对象为:实现了org.springframework.web.HttpRequestHandler 接口的类的实例。
Spring在适配器模式应用时做了适配职责的分离。
这样的设计和Java在设计类加载机制时相似,更灵活,易于扩展与维护。