将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作。
1. 类适配器
适配器通过 继承被适配类,实现目标接口 完成适配。
代码示例:
目标接口:
public interface Target {
void request();
}
被适配类:
public class Adaptee {
public void adapteeRequest() {
System.out.println("被适配者的方法");
}
}
适配器:
public class Adapter extends Adaptee implements Target{
@Override
public void request() {
//...一些操作...
super.adapteeRequest();
//...一些操作...
}
}
##################################
调用:
public static void main(String[] args) {
Target adapterTarget = new Adapter();
adapterTarget.request();
}
2. 对象适配器
适配器通过 关联被适配类,实现目标类 完成适配。
代码示例:
public class Adapter implements Target{
// 适配者是对象适配器的一个属性
private Adaptee adaptee = new Adaptee();
@Override
public void request() {
//...
adaptee.adapteeRequest();
//...
}
}
应用:
- List Arrays.asList(T[])就相当于一个转换器,它可以把数组转换为List;
- InputStreamReader 将 InputStream 转换为 Reader
InputStream input = Files.newInputStream(Paths.get("/path/to/file")); Reader reader = new InputStreamReader(input, "UTF-8");
- spring AOP中的适配器模式
在Spring的Aop中,使用的 Advice(通知) 来增强被代理类的功能。
Advice的类型有:MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice,
在每个类型 Advice 都有对应的拦截器,MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor;
Spring需要将每个 Advice 都封装成对应的拦截器类型,返回给容器,所以需要使用适配器模式对 Advice 进行转换。
三个适配者类 Adaptee 如下:
public interface MethodBeforeAdvice extends BeforeAdvice {
void before(Method var1, Object[] var2, @Nullable Object var3) throws Throwable;
}
public interface AfterReturningAdvice extends AfterAdvice {
void afterReturning(@Nullable Object var1, Method var2, Object[] var3, @Nullable Object var4) throws Throwable;
}
public interface ThrowsAdvice extends AfterAdvice {
}
目标接口:Target 有两个方法,一个判断 Advice 类型是否匹配,一个是工厂方法,创建对应类型的 Advice 对应的拦截器
public interface AdvisorAdapter {
boolean supportsAdvice(Advice var1);
MethodInterceptor getInterceptor(Advisor var1);
}
三个适配器类 Adapter 分别如下,注意其中的 Advice、Adapter、Interceptor之间的对应关系
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof MethodBeforeAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
}
@SuppressWarnings("serial")
class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof AfterReturningAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
return new AfterReturningAdviceInterceptor(advice);
}
}
class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof ThrowsAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
return new ThrowsAdviceInterceptor(advisor.getAdvice());
}
}
客户端 DefaultAdvisorAdapterRegistry
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
private final List<AdvisorAdapter> adapters = new ArrayList(3);
public DefaultAdvisorAdapterRegistry() {
// 这里注册了适配器
this.registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
this.registerAdvisorAdapter(new AfterReturningAdviceAdapter());
this.registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor)advice);
}
Iterator var4 = this.adapters.iterator();
while(var4.hasNext()) {
AdvisorAdapter adapter = (AdvisorAdapter)var4.next();
if (adapter.supportsAdvice(advice)) { // 这里调用适配器方法,判断 Advice 对应的类型,找到适合该advice(通知)的适配器
interceptors.add(adapter.getInterceptor(advisor)); // 这里调用适配器方法,创建对应类型的拦截器
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
} else {
return (MethodInterceptor[])interceptors.toArray(new MethodInterceptor[0]);
}
}
// ...省略...
}
这里看 while 循环里,逐个取出注册的适配器,调用 supportsAdvice() 方法来判断 Advice 对应的类型,然后调用 getInterceptor() 创建对应类型的拦截器。
这里应该属于对象适配器模式,关键字 instanceof 可看成是 Advice 的方法,不过这里的 Advice 对象是从外部传进来,而不是成员属性