浅谈springMVC中的设计模式(1)——责任链模式

浅谈Spring框架应用的设计模式(七)——责任链模式 Spring是目前Java企业级开发应用广泛的框架之一,其具有强大的生态,且得益于其提供的高扩展能力,能够减少开发成本,提高开发效率。如此优秀的框架,当然离不开各种设计模式,本文主要介绍设计模式中的责任链模式Spring框架中的应用。... 阅读详情

浅谈springMVC中的设计模式(1)——责任链模式

2018年03月17日 13:02:31 春天写下一个bug 阅读数:2481 标签: 设计模式springMVC责任链模式 更多

个人分类: 专题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.youkuaiyun.com/ljw761123096/article/details/79591133

最近终于闲了下来,准备自己记录些东西。网上关于springMVC的资料很多,但关于设计模式的还有限,我就想把springMVC源码中的设计模式抽出来做成一个系列,简单的谈一下其中的实现原理,作为一种学习分享,以后有更深的感悟也会更新。 
先从一张图对整个springMVC的运作流程有一个大致的了解,图片侵删。 
这里写图片描述

HandlerExecutionChain 
其中我们可以看到,在springMVC中,DispatcherServlet这个核心类中使用到了HandlerExecutionChain这个类,他就是责任链模式实行的具体类。在DispatcherServlet的doDispatch这个方法中,我们可以看到它贯穿了整个请求dispatch的流程:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;

        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            ModelAndView mv = null;
            Exception dispatchException = null;

            try {
                processedRequest = checkMultipart(request);
                multipartRequestParsed = (processedRequest != request);
                // 获取该请求的handler,每个handler实为HandlerExecutionChain,它为一个处理链,负责处理整个请求
                mappedHandler = getHandler(processedRequest);
                if (mappedHandler == null || mappedHandler.getHandler() == null) {
                    noHandlerFound(processedRequest, response);
                    return;
                }

                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

                String method = request.getMethod();
                boolean isGet = "GET".equals(method);
                if (isGet || "HEAD".equals(method)) {
                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                    if (logger.isDebugEnabled()) {
                        logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                    }
                    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }
                // 责任链执行预处理方法,实则是将请求交给注册的请求拦截器执行
                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }
                // 实际的执行逻辑的部分,也就是你加了@RequestMapping注解的方法
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
                applyDefaultViewName(processedRequest, mv);
                // 责任链执行后处理方法,实则是将请求交给注册的请求拦截器执行
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            }
            catch (Exception ex) {
                dispatchException = ex;
            }
            catch (Throwable err) {
                dispatchException = new NestedServletException("Handler dispatch failed", err);
            }
            // 处理返回的结果,触发责任链上注册的拦截器的AfterCompletion方法,其中也用到了HandlerExecutionChain注册的handler来处理错误结果
            processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        }
        catch (Exception ex) {
            // 触发责任链上注册的拦截器的AfterCompletion方法
            triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
        }
        catch (Throwable err) {
            triggerAfterCompletion(processedRequest, response, mappedHandler,
                    new NestedServletException("Handler processing failed", err));
        }
        finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            }
            else {
                if (multipartRequestParsed) {
                    cleanupMultipart(processedRequest);
                }
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

从上面的代码中我们可以看到,HandlerExecutionChain主要负责请求的拦截器的执行和请求的处理,但是他本身不处理请求,只是将请求分配给在链上注册的处理器执行,这是一种责任链的实现方式,减少了责任链本身与处理逻辑之间的耦合的同时,规范了整个处理请求的流程,下面我们看一下上面代码中涉及到的方法在HandlerExecutionChain类中对应的代码。

boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HandlerInterceptor[] interceptors = getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for (int i = 0; i < interceptors.length; i++) {
                HandlerInterceptor interceptor = interceptors[i];
                if (!interceptor.preHandle(request, response, this.handler)) {
                    triggerAfterCompletion(request, response, null);
                    return false;
                }
                this.interceptorIndex = i;
            }
        }
        return true;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
        HandlerInterceptor[] interceptors = getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for (int i = interceptors.length - 1; i >= 0; i--) {
                HandlerInterceptor interceptor = interceptors[i];
                interceptor.postHandle(request, response, this.handler, mv);
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex)
            throws Exception {

        HandlerInterceptor[] interceptors = getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for (int i = this.interceptorIndex; i >= 0; i--) {
                HandlerInterceptor interceptor = interceptors[i];
                try {
                    interceptor.afterCompletion(request, response, this.handler, ex);
                }
                catch (Throwable ex2) {
                    logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
                }
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

代码很容易理解,这里不详细说明。需要注意的是,HandlerExecutionChain维护了HandlerInterceptor(拦截器)的集合,可以向其中注册相应的HandlerInterceptor。

总结 
个人的理解,责任链模式可以很好的将原本耦合的顺序过程处理的代码和逻辑,解耦成执行的顺序逻辑,和一个个相对应的处理器(责任人),对应的责任链只需要关心责任处理的顺序,而不需要关心具体的处理逻辑,将这些逻辑交给注册的责任人去处理。从springMVC的源码中,我们可以看到这一设计模式的应用,将原本复杂的请求处理逻辑表现的清楚明白。

 

Java设计模式之<责任链模式> 本文介绍了责任链模式的概念、实现及应用场景。责任链模式是一种行为型设计模式,通过将请求沿处理链传递,直到被某个对象处理。其核心思想是解耦请求发送者和接收者,支持动态组合处理链,适用于多级处理场景。文章详细说明了该模式的优缺点,并通过Java代码示例展示了具体实现方式。此外,还列举了SpringMVC、MyBatis、Spring拦截器等多个框架中的实际应用案例,最后以学校采购审批流程为例,完整演示了责任链模式的具体实现过程。该模式能有效分离职责,提高系统灵活性。 阅读详情

相关推荐

详解SpringBoot结合策略模式实战套路

主要介绍了详解SpringBoot结合策略模式实战套路,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

SpringMVC中的责任链模式详解

本文以SpringMVC源码为依据来学习设计模式之责任链模式在框架中的落地。

qq_35876365的博客 764

牛耕式全覆盖算法-matlab代码

牛耕式路径全覆盖算法,也称为牛耕算法或者蚂蚁算法,是一种用于解决路径规划问题的启发式算法。这个算法的灵感来自于牛在耕田时的行为。在这个算法中,假设有一块田地需要耕作,牛从田地的某个角落开始行走,走过的路径会被标记。牛会优先选择尚未经过的路径,当所有的路径都走过后,算法停止。在路径规划问题中,田地可以看作是一个由节点和边构成的图。每个节点代表一个位置,每条边代表两个节点之间的连接。路径全覆盖问题是找出一组路径,使得每个节点都被至少一条路径经过。牛耕式路径全覆盖算法的基本思想是以启发式的方式逐步构建路径。

m0_69611489的博客 1689

设计模式之责任链模式(附:spring mvc中HandlerExecutionChain源码应用分析)

一、概述 1、定义         Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object

qq_42339210的博客 783

避坑指南:中国地面气候日值数据集(V3.0)处理中的常见错误与解决方案

本文详细解析了中国地面气候日值数据集(V3.0)处理中的常见错误与解决方案,包括数据清洗、特征值解码、时间序列处理和质量控制等关键步骤。通过Python实战代码示例,帮助研究者高效处理这一包含全国699个气象站多要素日值数据的数据集,避免常见陷阱,提升气候变化研究和农业气象分析的准确性。

xray4的博客 1026

python爬取淘宝数据

python爬取淘宝数据淘宝评论 淘宝评论 打开淘宝,选择打开需要爬取的商品的评论。在谷歌浏览器选择开发者工具,选择network,找到list_detail_rate.htm?itemId=624466733121,点击headers、previews,可以看见相应的评论数据。 爬取一页屏评论代码如下 import re import requests headers = { 'Referer': '在headers中', 'User-Agent': '在

qq_36333776的博客 5797

SpringMVC中的设计模式——责任链模式

定义: 使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。 优点: 将请求者和处理者分开,两者解耦,提供系统灵活性。 角色: 1、抽象处理者(Handle):定义一个处理请求的接口。如果需要可以定义出一个方法以设定和返回 对下家的引用。这个角色通常由一个Java抽象类或者Java接口实...

码放南山 1627

Python异步协程爬虫优化:解决aiohttp中ServerDisconnectedError的高效策略

本文深入探讨了在Python异步协程爬虫中使用aiohttp时,如何高效解决常见的ServerDisconnectedError问题。核心策略包括全局复用ClientSession、精细配置TCPConnector连接池、实施请求重试与速率限制,从而构建稳定、高效的异步爬虫架构,有效避免服务器断开连接错误。

pz890123的博客 859

《程序猿之设计模式实战 · 责任链模式》

本篇文章继续介绍一下责任链模式,这个在日常工作中使用较为频繁,责任链模式可以带给我们什么?SpringMVC的拦截器是否使用了责任链模式呢?让我们一探究竟。《程序猿之设计模式实战 · 策略模式》《程序猿之设计模式实战 · 装饰者模式》《程序猿之设计模式实战 · 池化思想》《程序猿之设计模式实战 · 观察者模式》1、责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许将请求的发送者和接收者解耦。

山人行 1398

ADB命令解锁Android手机屏幕的3种实用方法(附详细步骤)

本文详细介绍了在Android手机屏幕失灵或密码遗忘时,利用ADB命令解锁屏幕的三种实用方法。包括通过ADB模拟输入事件、移除锁屏认证文件(需Root权限)以及结合恢复模式抢救数据。文章提供了详细的操作步骤与风险提示,强调提前开启USB调试的重要性,是Android用户应对紧急锁屏情况的有效技术指南。

weixin_29229055的博客 919

Fiddler抓包实战:5分钟搞定微信公众号历史消息接口分析(附完整Python代码)

本文详细介绍了如何使用Fiddler抓包工具逆向分析微信公众号历史消息接口,并提供完整的Python代码实现。从环境准备、动态参数捕获到商业级采集系统架构设计,全面解析了突破官方接口限制的技术方案,帮助开发者高效获取公众号文章数据。

tree8的博客 329

java设计模式---责任链模式详解

深入理解责任链模式

zhenghuishengq的博客 2万+

基于Pycatia的智能孔特征识别技术:无参模型圆心自动化提取方案

基于Pycatia的智能孔特征识别技术:无参模型圆心自动化提取方案

KE17RS的博客 2877

Java设计模式之责任链模式(UML类图分析+代码详解)

职责链模式(Chain of Responsibility Pattern), 又叫 责任链模式,为请求创建了一个接收者 对象的链(简单示意图)。这种模式对请求的 发送者和接收者进行解耦。职责链模式通常每个接收者都包含对另一个接 收者的引用。如果一个对象不能处理该请求, 那么它会把相同的请求传给下一个接收者,依 此类推。这种类型的设计模式属于行为型模式。

m0_51750419的博客 5687

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

字节面试:什么是责任链模式?

整挺好

敖丙 7213

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

浅谈责任链设计模式在框架源码中的运用

写在前面,该篇博文为我在部门的技术分享,分享时长约40分钟。以至于文章中更多的只有源代码截图,更多细节为现场口述。本文更像是一个大纲,通过6+3个真实的责任链代码实现,为我们能够灵活运用责任链设计模式添砖加瓦。希望对你有帮助!

持续Java学习中 1295

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

springmvc5中设计模式

用了5种设计模式 组合模式 责任链模式 适配器模式 策略模式 组合模式 WebMvcConfigurerComposite体现了组合模式 树枝节点用Composite结尾,里面包含了树叶节点,树枝和树叶都实现了相同的抽象类或接口WebMvcConfigurer class WebMvcConfigurerComposite implements WebMvcConfigurer { pri...

mingwulipo的博客 8616

设计模式七:责任链模式

责任链模式为请求创建了一个接收者对象的链,在这种模式下,通常每个节点都包含对另一个节点者的引用。每个节点针对请求,处理自己感兴趣的内容,处理完之后可以结束,也可以向下一个节点传递继续处理;这种形式很难进行动态新增和调整处理节点,一种比较复杂的控制节点的形式如Netty中的责任链模式应用,见下一节。Netty中的handler使用了责任链模式,但是其中回调过多,责任链模式的体现不清晰,参考该文章**:为链条中节点的上下文,它里面有链条的前一个节点和后一个节点的。​ 2.可以灵活添加新的责任链中的对象。

qq_41845823的博客 1205

责任链模式专题

举个例子,SpringMvc 中可以定义拦截器,并且可以定义多个。当一个用户发起请求时,顺利的话请求会经过所有拦截器,最终到达业务代码逻辑,SpringMvc 拦截器设计就是使用了责任链模式。为什么说顺利的话会经过所有拦截器?因为请求不满足拦截器自定义规则会被打回,但这并不是责任链模式的唯一处理方式,继续往下看。在责任链模式中,多个处理器(参照上述拦截器)依次处理同一个请求。

weixin_62827806的博客 1104

行为型设计模式——责任链模式

责任链模式(Chain of responsibility pattern): 通过责任链模式, 你可以为某个请求创建一个对象链. 每个对象依序检查此请求并对其进行处理或者将它传给链中的下一个对象。

庄小焱 3250

设计模式在Spring中的精妙应用:责任链模式与拦截器的协作之道

在软件开发领域,责任链模式(Chain of Responsibility Pattern)是一种经典的行为型设计模式,它通过构建一条处理对象链,将请求沿着这条链传递,直到有对象处理它为止。这种模式为请求创建了一个接收者对象的链,使多个对象都有机会处理请求,从而避免了请求发送者与接收者之间的耦合关系。随着云原生和微服务架构的持续演进,责任链模式正在展现出前所未有的适应性和扩展性。在2025年的技术生态中,这种经典设计模式不仅没有过时,反而因其天然的松耦合特性,成为了构建复杂系统的重要基石。

zuiyuelong的博客 984

设计模式之责任链模式

责任链模式 菜鸟教程 - 责任链模式 五分钟设计模式 - 12责任链模式 尚硅谷 介绍 责任链模式(Chain of Responsibility Pattern)是一种处理请求的模式,它让多个处理器都有机会处理该请求,直到其中某个处理成功为止。责任链模式把多个处理器串成链,然后让请求在链上传递。 属于行为型设计模式 优点: 将请求与处理分开,请求者不需要知道谁去处理,处理者也不需要知道请求的全貌 灵活,方便新增或删除结点 缺点: 效率低。比如某个请求需要最高级别的处理器来处理,但你仍然需要一级一级

mrhanzhou5273的博客 251

一文带你彻底搞懂什么是责任链模式!!

本篇文章带你彻底读懂什么是责任链模式!

祝你身体健康,美满幸福 1388

java设计模式学习之【责任链模式】

这篇教程不仅提供了责任链模式的理论基础,还通过具体的Java代码示例展示了如何实现和应用这种模式。简单理解,通俗易懂

qq_33129875的博客 1328
上一篇: SPRING与设计模式---责任链模式
下一篇: spring aop学习9:Aop的链式调用(责任链模式)
javaPie
博客等级 码龄16年 1171粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值