文档章节

责任链模式在典型使用方式

lizo
 lizo
发布于 2017/09/11 10:39
字数 882
阅读 13
收藏 1
点赞 0
评论 0

责任链模式

责任链模式的定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。这里就不再过多的介绍什么是责任链模式,主要来说说java中如何编写。主要从下面3个框架中的代码中介绍。

  • servlet中的filter
  • dubbo中的filter
  • mybatis中的plugin 这3个框架在实现责任链方式不尽相同。

servlet中的Filter

servlet中分别定义了一个 Filter和FilterChain的接口,核心代码如下:

public final class ApplicationFilterChain implements FilterChain {
    private int pos = 0; //当前执行filter的offset
    private int n; //当前filter的数量
    private ApplicationFilterConfig[] filters;  //filter配置类,通过getFilter()方法获取Filter
    private Servlet servlet 
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response) {
        if (pos < n) {
            ApplicationFilterConfig filterConfig = filters[pos++];
            Filter filter = filterConfig.getFilter();
            filter.doFilter(request, response, this);
        } else {
            // filter都处理完毕后,执行servlet
            servlet.service(request, response);
        }
    }
 
}

代码还算简单,结构也比较清晰,定义一个Chain,里面包含了Filter列表和servlet,达到在调用真正servlet之前进行各种filter逻辑。

输入图片说明

Dubbo中的Filter

Dubbo在创建Filter的时候是另外一个方法,通过把Filter封装成 Invoker的匿名类,通过链表这样的数据结构来完成责任链,核心代码如下:

private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {
    Invoker<T> last = invoker;
    //只获取满足条件的Filter
    List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
    if (filters.size() > 0) {
        for (int i = filters.size() - 1; i >= 0; i --) {
            final Filter filter = filters.get(i);
            final Invoker<T> next = last;
            last = new Invoker<T>() {
                ...
                public Result invoke(Invocation invocation) throws RpcException {
                    return filter.invoke(next, invocation);
                }
                ...
            };
        }
    }
    return last;
}

Dubbo的责任链就没有类似FilterChain这样的类吧Filter和调用Invoker结合起来,而是通过创建一个链表,调用的时候我们只知道第一个节点,每个节点包含了下一个调用的节点信息。 这里的虽然Invoker封装Filter没有显示的指定next,但是通过java匿名类和final的机制达到同样的效果。
输入图片说明

Mybatis中的Plugin

Mybatis可以配置各种Plugin,无论是官方提供的还是自己定义的,Plugin和Filter类似,就在执行Sql语句的时候做一些操作。Mybatis的责任链则是通过动态代理的方式,使用Plugin代理实际的Executor类。(这里实际还使用了组合模式,因为Plugin可以嵌套代理),核心代码如下:

public class Plugin implements InvocationHandler{
    private Object target;
    private Interceptor interceptor;
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {       
        if (满足代理条件) {
            return interceptor.intercept(new Invocation(target, method, args));
        }
        return method.invoke(target, args);      
    }
  
    //对传入的对象进行代理,可能是实际的Executor类,也可能是Plugin代理类
    public static Object wrap(Object target, Interceptor interceptor) {
 
        Class<?> type = target.getClass();
        Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
        if (interfaces.length > 0) {
            return Proxy.newProxyInstance(
                    type.getClassLoader(),
                    interfaces,
                    new Plugin(target, interceptor, signatureMap));
        }
        return target;
    }
}  

输入图片说明

总结

这里简单介绍了Servlet、Dubbo、Mybatis对责任链模式的不同实现手段,其中Servlet是相对比较清晰,又易于实现的方式,而Dubbo和Mybatis则适合在原有代码基础上,增加责任链模式代码改动量最小的。

© 著作权归作者所有

共有 人打赏支持
lizo
粉丝 58
博文 39
码字总数 48903
作品 0
杭州
程序员
23种设计模式总结(三)

前面2节,我们主要介绍了构建型和结构型的设计模式,今天我们重点讲一下行为型。 策略模式 要点:一个策略的接口,若干个实现类,针对不同的情况,选择不同的策略实现来解决问题。 典型场景:...

大胖和二胖 ⋅ 2016/11/29 ⋅ 0

Tomcat 系统架构与设计模式_ 设计模式分析

门面设计模式 门面设计模式在 Tomcat 中有多处使用,在 Request 和 Response 对象封装中、Standard Wrapper 到 ServletConfig 封装中、ApplicationContext 到 ServletContext 封装中等都用到...

lvzjane ⋅ 2014/11/03 ⋅ 0

23种设计模式总结(一)

总体来说分为3类: 创建型:工厂方法模式、抽象工厂模式、单例、建造者、原型 结构型:适配器、装饰器、代理、外观、桥接、组合、享元 行为型:策略、模板方法、观察者、迭代子、责任链、命令...

大胖和二胖 ⋅ 2016/11/28 ⋅ 0

FP角度下的责任链模式(中间件模式,middleware)

责任链模式,十分常见,比如说,j2ee里的filter,express里的middleware,redux里的middleware 问题是:怎么才可以用最简单的方式实现一个责任链模式? 用数组,链表来记录中间件?这些都想过...

m2012 ⋅ 2015/12/10 ⋅ 0

用kotlin打印出漂亮的android日志(三)——基于责任链模式打印任意对象

SAF-Kotlin-log 是一个Android的日志框架,这几天我抽空重新更新了一下代码。 github地址:https://github.com/fengzhizi715/SAF-Kotlin-log 一. 打印几个Android常用的对象 1.1 Uri的打印 ...

fengzhizi715 ⋅ 2017/11/28 ⋅ 0

Design Patterns in Android:责任链模式

前言 非常抱歉,本系列博客长达半年没更新了,今日偶得灵感,更新一波《设计模式Android篇:责任链模式》。点击此处查看《Design Patterns in Android》系列其他文章。 本文原创作者MichaelX。...

MichaelX ⋅ 05/14 ⋅ 0

C# 设计模式 责任链

责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户...

lindexi_gd ⋅ 2017/10/25 ⋅ 0

关于Handle执行中的责任链模式使用

@JFinal 你好,波总: 小弟不才,昨天在看Controller中init()执行的时候,看到了是在ActionHandle中执行的,然后我就又跟着看了下Handle的处理逻辑,并且也发现了ActionHandle确实也是最后执...

Ajsgn ⋅ 2016/07/08 ⋅ 2

《JAVA与模式》之责任链模式

详细请访问原博客:http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html 在阎宏博士的《JAVA与模式》一书中开头是这样描述责任链(Chain of Responsibility)模式的:   ...

方绍伟 ⋅ 2014/02/27 ⋅ 0

小白的设计模式之旅(初识—责任链模式)

每个IT小白都有一颗技术大老的心,然而想学会十八般武艺却如蜀道之路步步艰难!想要迈出搬砖的生活,需要去学习技术的深度,宽展思想的广度,加强技术的历炼,从今天开始接触不一样的代码,不...

cjsy_2011 ⋅ 05/23 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Centos7重置Mysql 8.0.1 root 密码

问题产生背景: 安装完 最新版的 mysql8.0.1后忘记了密码,向重置root密码;找了网上好多资料都不尽相同,根据自己的问题总结如下: 第一步:修改配置文件免密码登录mysql vim /etc/my.cnf 1...

豆花饭烧土豆 ⋅ 今天 ⋅ 0

熊掌号收录比例对于网站原创数据排名的影响[图]

从去年下半年开始,我在写博客了,因为我觉得业余写写博客也还是很不错的,但是从2017年下半年开始,百度已经推出了原创保护功能和熊掌号平台,为此,我也提交了不少以前的老数据,而这些历史...

原创小博客 ⋅ 今天 ⋅ 0

LVM讲解、磁盘故障小案例

LVM LVM就是动态卷管理,可以将多个硬盘和硬盘分区做成一个逻辑卷,并把这个逻辑卷作为一个整体来统一管理,动态对分区进行扩缩空间大小,安全快捷方便管理。 1.新建分区,更改类型为8e 即L...

蛋黄Yolks ⋅ 今天 ⋅ 0

Hadoop Yarn调度器的选择和使用

一、引言 Yarn在Hadoop的生态系统中担任了资源管理和任务调度的角色。在讨论其构造器之前先简单了解一下Yarn的架构。 上图是Yarn的基本架构,其中ResourceManager是整个架构的核心组件,它负...

p柯西 ⋅ 今天 ⋅ 0

uWSGI + Django @ Ubuntu

创建 Django App Project 创建后, 可以看到路径下有一个wsgi.py的问题 uWSGI运行 直接命令行运行 利用如下命令, 可直接访问 uwsgi --http :8080 --wsgi-file dj/wsgi.py 配置文件 & 运行 [u...

袁祾 ⋅ 今天 ⋅ 0

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

推荐:并发情况下:Java HashMap 形成死循环的原因

在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。这个事情我4、5年前也经历...

码代码的小司机 ⋅ 昨天 ⋅ 2

聊聊spring cloud gateway的RetryGatewayFilter

序 本文主要研究一下spring cloud gateway的RetryGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/G......

go4it ⋅ 昨天 ⋅ 0

创建新用户和授予MySQL中的权限教程

导读 MySQL是一个开源数据库管理软件,可帮助用户存储,组织和以后检索数据。 它有多种选项来授予特定用户在表和数据库中的细微的权限 - 本教程将简要介绍一些选项。 如何创建新用户 在MySQL...

问题终结者 ⋅ 昨天 ⋅ 0

android -------- 颜色的半透明效果配置

最近有朋友问我 Android 背景颜色的半透明效果配置,我网上看资料,总结了一下, 开发中也是常常遇到的,所以来写篇博客 常用的颜色值格式有: RGB ARGB RRGGBB AARRGGBB 这4种 透明度 透明度...

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部