美文网首页设计模式@IT·互联网程序员
常用开源框架中设计模式使用分析- 适配器模式(Adapter P

常用开源框架中设计模式使用分析- 适配器模式(Adapter P

作者: 阿里加多 | 来源:发表于2017-05-24 14:29 被阅读105次

    十、适配器模式(Adapter Pattern)

    10.1 介绍

    适配器模式属于结构性模式,它为两个不同接口之间互通提供了一种手段。

    阿里巴巴长期招聘Java研发工程师p6,p7,p8等上不封顶级别,有意向的可以发简历给我,注明想去的部门和工作地点:1064454834@qq.com_

    10.2 Spring中MethodInterceptor适配器

    在Spring Aop框架中,MethodInterceptor接口被用来拦截指定的方法,对方法进行增强。

    image.png

    大家都知道在Aop中每个advistor 里面会有一个advice具体做切面动作,Spring提供了AspectJAfterReturningAdvice,AspectJMethodBeforeAdvice,AspectJAroundAdvice,AspectJAfterAdvice这几个advice,在XML 配置aop时候会指定<aop:after-returning/>,<aop:before/>,<aop:around/>,<aop:after/>,其实内部就是创建上面对应的这些advice。

    从图知道AspectJAfterReturningAdvice和AspectJMethodBeforeAdvice没有实现MethodInterceptor接口,其他两者则实现了该接口。而Spring Aop的方法拦截器却必须是实现了MethodInterceptor的,所以Spring提供了对应的适配器来适配这个问题,分别是MethodBeforeAdviceAdapter和AfterReturningAdviceAdapter和ThrowsAdviceAdapter。

    image.png

    看下DefaultAdvisorAdapterRegistry的 getInterceptors方法:

    public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
    
        //从advistor中获取advice
        Advice advice = advisor.getAdvice();
    
        //如果实现了MethodInterceptor则直接加入,比如AspectJAroundAdvice,AspectJAfterAdvice
        if (advice instanceof MethodInterceptor) {
            interceptors.add((MethodInterceptor) advice);
        }
    
        //否者看是否有当前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()]);
    }
    

    以MethodBeforeAdviceAdapter为例子看下:

    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);
        }
    
    }
    
    public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
    
        private MethodBeforeAdvice advice;
    
    
        /**
         * Create a new MethodBeforeAdviceInterceptor for the given advice.
         * @param advice the MethodBeforeAdvice to wrap
         */
        public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
            Assert.notNull(advice, "Advice must not be null");
            this.advice = advice;
        }
    
        public Object invoke(MethodInvocation mi) throws Throwable {
            this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
            return mi.proceed();
        }
    
    }
    

    可知MethodBeforeAdviceInterceptor继承了MethodInterceptor作为了一个适配器内部委托请求给MethodBeforeAdvice。

    10.3 使用场景

    • 两个系统交互时候由于接口参数不一样没办法直接对接,则可以搞个适配器接口做参数转换。

    • 适配器模式经常是在一个系统或者设计已经定型时候用的,而不是在初始设计时候。一般是因为不影响现在业务情况下,通过适配方式统一接口

    欢迎关注微信公众号:技术原始积累 获取更多技术干货

    image.png

    相关文章

      网友评论

      • Spring_java:谢谢作者,以前只看到了一个动态代理,没想到里面还有个适配器

      本文标题:常用开源框架中设计模式使用分析- 适配器模式(Adapter P

      本文链接:https://www.haomeiwen.com/subject/vasnxxtx.html