1. 程式人生 > >設計模式系列---適配器模式

設計模式系列---適配器模式

private 字節碼 攔截 代理 bsp 攔截器 xtend 我們 客戶

寫在前面

  適配模式的定義如下:

  將一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配兒無法在一起工作的兩個類能夠在一起工作。 看下適配器模式的類圖:

技術分享

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);  
    }  
  
}  

設計模式系列---適配器模式