前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >常用开源框架中设计模式使用分析- 适配器模式(Adapter Pattern)

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

作者头像
加多
发布于 2018-09-06 06:48:50
发布于 2018-09-06 06:48:50
96000
代码可运行
举报
文章被收录于专栏:Java编程技术Java编程技术
运行总次数:0
代码可运行

十、适配器模式(Adapter Pattern)

10.1 介绍

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

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方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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为例子看下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 使用场景

  • 两个系统交互时候由于接口参数不一样没办法直接对接,则可以搞个适配器接口做参数转换。
  • 适配器模式经常是在一个系统或者设计已经定型时候用的,而不是在初始设计时候。一般是因为不影响现在业务情况下,通过适配方式统一接口
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.05.24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 十、适配器模式(Adapter Pattern)
    • 10.1 介绍
    • 10.2 Spring中MethodInterceptor适配器
    • 10.3 使用场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档