适配器的概念:
将一个类的接口转换成客户期望的另一个接口。使得原本由于接口不匹配而不能一起工作的类可以一起工作。
客户期望的接口A是供应接口,而提供的接口B为需求接口。适配器的适配就是指 需求“适配”供应。
假如我的手机充电口是type-c类型的,但我只有一根传统的Micro USB接口的数据线,怎么办?
type-c类型的接口就是需求接口,Micro USB类型的接口是供应接口,想让需求匹配供应,就需要有一个适配器。
适配器的三种实现方式:
1. 类适配器
当需要把一个已经实现了接口A的类A转换成 能 实现接口B的类时,可使用类适配器模式。
注意:类A是已经设计好的,不能改变。可以把接口A看作需求接口,接口B看作供应接口。
通过继承特性实现适配器功能。创建一个新类,实现接口,继承原有的类即可。
// 供应接口
public interface MicroUsb {
public void microUsb();
}
// 需求接口
public interface TypeC {
public void typeC();
}
// 需求实现类
public class Phone implements TypeC{
public void typeC() {
System.out.println("Type-C接口");
}
}
// 适配器
public class Adapter extends Phone implements MicroUsb{
public void microUsb() {
typeC();
}
}
// 测试类
public class Test {
public static void main(String[] args) {
MicroUsb microUsb = new Adapter();
microUsb.microUsb();
}
}
2. 对象适配器
当希望将接口A的实现类A的对象转换成满足接口B的对象时,可使用对象适配器的方式。
通过组合方式实现适配器功能。将接口A的对象封装在适配器中,同时适配器继承接口B,便可将接口A类型转换为接口B类型。
// 供应接口
public interface MicroUsb {
public void microUsb();
}
// 需求接口
public interface TypeC {
public void typeC();
}
// 需求实现类
public class Phone implements TypeC{
public void typeC() {
System.out.println("Type-C接口");
}
}
// 适配器
public class Adapter implements MicroUsb{
private TypeC typeC;
public Adapter(TypeC typeC){
this.typeC=typeC;
}
@Override
public void microUsb() {
typeC.isTypeC();
}
}
// 测试类
public class Test {
public static void main(String[] args) {
TypeC typeC = new Phone();
MicroUsb microUsb = new Adapter(typeC);
microUsb.microUsb();
}
}
3. 接口适配器
有一个很大的接口,包含很多方法,当不希望实现接口中的所有方法时,可创建一个抽象类继承接口,但方法实现都是空的,实现类可继承这个抽象类实现了适配器的功能。
构建一个情景:日常用的转换器有很多种类型的接口,比如type-C,VGA,Hdmi,可以把这些类型都放在一个大的接口中,当我只需type-C和VGA类型的转换器时,继承相关的类即可。
// 接口类
public interface AllPorts {
public void isTypeC();
public void isVGA();
public void isHdmi();}
// 适配器的框架
public abstract class Adapter implements AllPorts{
@Override public void isTypeC() { }
@Override public void isVGA() { }
@Override public void isHdmi() { }
}
// 适配器类
public class TypecToVGA extends Adapter{
@Override public void isTypeC() {
System.out.println("信号从TypeC接口进入");
}
@Override
public void isVGA() {
System.out.println("信号从VGA接口出");
}
}
// 测试类
public class Test {
public static void main(String[] args) {
TypecToVGA typecToVGA = new TypecToVGA();
typecToVGA.isTypeC();
typecToVGA.isVGA();
}
}
适配器模式在Spring MVC中的应用:
HandlerMapping 是可以有多种实现的,Spring会遍历这些具体的实现类,判断哪一个能够根据当前request产生一个handler,因而对于HandlerAdapter而言,其是不知道当前获取到的 handler 具体是什么形式的,不同的HandlerMapping 产生的handler形式是不一样的。
DispatcherServlet 会根据 HandlerMapping 传过来的 handler与HandlerAdapter的实现类一一匹配,如果找到了其中一种HandlerAdapter支持传过来的 handler 类型,那么该HandlerAdapter会调用自己的 handle 方法处理该请求。
首先看一下HandlerAdapter接口的内部方法:
public interface HandlerAdapter {
// 判断当前 HandlerAdapter 是否支持处理该handle
boolean supports(Object var1);
// 利用handle处理请求
@Nullable
ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
long getLastModified(HttpServletRequest var1, Object var2);
}
HandlerAdapter的实现类:
1. HttpRequestHandlerAdapter ,处理HttpRequestHandler类型的handler
public class HttpRequestHandlerAdapter implements HandlerAdapter {
public HttpRequestHandlerAdapter() {
}
public boolean supports(Object handler) {
return handler instanceof HttpRequestHandler;
}
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
((HttpRequestHandler)handler).handleRequest(request, response);
return null;
}
2. SimpleServletHandlerAdapter,处理Servlet类型的handler
public class SimpleServletHandlerAdapter implements HandlerAdapter {
public SimpleServletHandlerAdapter() {
}
public boolean supports(Object handler) {
return handler instanceof Servlet;
}
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
((Servlet)handler).service(request, response);
return null;
}
3. SimpleControllerHandlerAdapter是Controller处理适配器,适配实现了Controller接口或Controller接口子类的处理器,比如我们自己写的Controller来继承MultiActionController.
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
public SimpleControllerHandlerAdapter() {
}
public boolean supports(Object handler) {
return handler instanceof Controller;
}
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return ((Controller)handler).handleRequest(request, response);
}
4.AbstractHandlerMethodAdapter
在这里 AbstractHandlerMethodAdapter
只有一个实现子类就是 RequestMappingHandlerAdapter
,首先我们来看下其内部是怎么来实现判断 supports(..)
是否支持该 handler
以及 handler
解析方法 handle
:
public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {
private int order = 2147483647;
public AbstractHandlerMethodAdapter() {
super(false);
}
public void setOrder(int order) {
this.order = order;
}
public int getOrder() {
return this.order;
}
// 由子类实现是否支持解析该 HandlerMethod 对象
public final boolean supports(Object handler) {
return handler instanceof HandlerMethod && this.supportsInternal((HandlerMethod)handler);
}
protected abstract boolean supportsInternal(HandlerMethod var1);
// handle解析方法
@Nullable
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return this.handleInternal(request, response, (HandlerMethod)handler);
}
// 抽象方法,由子类实现具体的HandleMethod解析逻辑
@Nullable
protected abstract ModelAndView handleInternal(HttpServletRequest var1, HttpServletResponse var2, HandlerMethod var3) throws Exception;