设计模式系列---适配器模式

Posted 千寻

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式系列---适配器模式相关的知识,希望对你有一定的参考价值。

写在前面

  适配模式的定义如下:

  将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配儿无法在一起工作的两个类能够在一起工作。 看下适配器模式的类图:

 

spring中的适配器模式

  在Spring的Aop中,使用的Advice(通知)来增强被代理类的功能。Spring实现这一AOP功能的原理就使用代理模式(1、JDK动态代理。2、CGLib字节码生成技术代理。)对类进行方法级别的切面增强,即,生成被代理类的代理类, 并在代理类的方法前,设置拦截器,通过执行拦截器重的内容增强了代理方法的功能,实现的面向切面编程。

  Advice(通知)的类型有:BeforeAdvice、AfterReturningAdvice、ThreowSadvice的。

  在每个类型Advice(通知)都有对应的拦截器,MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor。

  Spring需要将每个Advice(通知)都封装成对应的拦截器类型,返回给容器,所以需要使用适配器模式对Advice进行转换。下面我们看看具体的代码。

 

spring中的实例

MethodBeforeAdvice类:Adaptee

public interface MethodBeforeAdvice extends BeforeAdvice {  
    void before(Method method, Object[] args, Object target) throws Throwable;  
}  

Adapter类接口:Target

 

public interface AdvisorAdapter {  
    boolean supportsAdvice(Advice advice);  
    MethodInterceptor getInterceptor(Advisor advisor);  
} 

MethodBeforeAdviceAdapter类,Adapter

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {  
    public boolean supportsAdvice(Advice advice) {  
        return (advice instanceof MethodBeforeAdvice);  
    }  
  
    public MethodInterceptor getInterceptor(Advisor advisor) {  
        MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();  
        return new MethodBeforeAdviceInterceptor(advice);  
    }  
}  

 

DefaultAdvisorAdapterRegistry类,Client

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {  
    private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);  
    /** 
     * Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters. 
     */  
    public DefaultAdvisorAdapterRegistry() {//这里注册了适配器  
        registerAdvisorAdapter(new MethodBeforeAdviceAdapter());  
        registerAdvisorAdapter(new AfterReturningAdviceAdapter());  
        registerAdvisorAdapter(new ThrowsAdviceAdapter());  
    }  
  
    public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {  
        if (adviceObject instanceof Advisor) {  
            return (Advisor) adviceObject;  
        }  
        if (!(adviceObject instanceof Advice)) {  
            throw new UnknownAdviceTypeException(adviceObject);  
        }  
        Advice advice = (Advice) adviceObject;  
        if (advice instanceof MethodInterceptor) {  
            // So well-known it doesn\'t even need an adapter.  
            return new DefaultPointcutAdvisor(advice);  
        }  
        for (AdvisorAdapter adapter : this.adapters) {  
            // Check that it is supported.  
            if (adapter.supportsAdvice(advice)) {//这里调用了适配器的方法  
                return new DefaultPointcutAdvisor(advice);  
            }  
        }  
        throw new UnknownAdviceTypeException(advice);  
    }  
  
    public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {  
        List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);  
        Advice advice = advisor.getAdvice();  
        if (advice instanceof MethodInterceptor) {  
            interceptors.add((MethodInterceptor) advice);  
        }  
        for (AdvisorAdapter adapter : this.adapters) {  
            if (adapter.supportsAdvice(advice)) {//这里调用了适配器的方法  
                interceptors.add(adapter.getInterceptor(advisor));  
            }  
        }  
        if (interceptors.isEmpty()) {  
            throw new UnknownAdviceTypeException(advisor.getAdvice());  
        }  
        return interceptors.toArray(new MethodInterceptor[interceptors.size()]);  
    }  
  
    public void registerAdvisorAdapter(AdvisorAdapter adapter) {  
        this.adapters.add(adapter);  
    }  
  
}  

 

以上是关于设计模式系列---适配器模式的主要内容,如果未能解决你的问题,请参考以下文章

C#设计模式系列:适配器模式(Adapter)

设计模式系列---适配器模式

设计模式学习系列——适配器模式

深入理解JavaScript系列(39):设计模式之适配器模式

Java程序设计模式系列之适配器模式

Java设计模式系列适配器模式及适用场景详解