zoukankan      html  css  js  c++  java
  • 设计模式系列---适配器模式

    写在前面

      适配模式的定义如下:

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

    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);  
        }  
      
    }  
  • 相关阅读:
    iOS遍历程序内某个文件夹下所有文件的属性
    CATransition 转场动画
    Xcode安装的推送证书所在目录
    UIMenuController 实现长按显示自定义菜单功能
    ios调用第三方程序打开文件,以及第三方调用自己的APP打开文件
    购物车界面,不同section,点击增减物品,确定取消选中的逻辑判断
    iOS UINavigationController
    iOS9 URL Schme 白名单
    iOS9 HTTPS
    iOS9 后台定位
  • 原文地址:https://www.cnblogs.com/chihirotan/p/7363883.html
Copyright © 2011-2022 走看看