文章目录
- 概念
- 组成角色
- 相关图示
- 示例代码
- 框架中的应用
- 适用场景:
概念
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,其主要目的是将请求的发送者和接收者解耦。这种模式创建了一系列处理器对象,每个处理器都有一个对应的处理逻辑。当一个请求到来时,这些处理器按照顺序处理请求,直到其中一个处理器成功处理请求为止。
组成角色
- 抽象处理器(Handler):定义了一个处理请求的接口,包含一个指向下一个处理器的引用。
- 具体处理器(ConcreteHandler):实现抽象处理器接口,执行具体的处理逻辑,并决定请求是否传递给下一个处理器。
- 客户端(Client):负责创建处理器链,并向处理器链发送请求。
相关图示

示例代码
//定义抽象处理器(Handler)
abstract class Handler {
    protected Handler nextHandler;
    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }
    public abstract void handleRequest(String request);
}
//定义具体处理器(ConcreteHandler) HandlerA、HandlerB、HandlerC
class HandlerA extends Handler {
    @Override
    public void handleRequest(String request) {
        if ("A".equals(request)) {
            System.out.println("Handler A is processing the request");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}
class HandlerB extends Handler {
    @Override
    public void handleRequest(String request) {
        if ("B".equals(request)) {
            System.out.println("Handler B is processing the request");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}
class HandlerC extends Handler {
    @Override
    public void handleRequest(String request) {
        if ("C".equals(request)) {
            System.out.println("Handler C is processing the request");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}
//客户端代码
public class Client {
    public static void main(String[] args) {
      	/**客户端创建了三个具体处理器,并将它们连接成一个处理器链。当客户端向处理器链发送请求时,处理器会按照顺序处理请求,直到其中一个处理器成功处理请求为止。**/
        // 创建处理器对象
        Handler handlerA = new HandlerA();
        Handler handlerB = new HandlerB();
        Handler handlerC = new HandlerC();
        // 构建处理器链
        handlerA.setNextHandler(handlerB);
        handlerB.setNextHandler(handlerC);
        // 发送请求
        handlerA.handleRequest("A");
        handlerA.handleRequest("B");
        handlerA.handleRequest("C");
        handlerA.handleRequest("D");
    }
}
框架中的应用
拦截器链(Interceptor Chain):在Spring MVC框架中,当请求经过过滤器链处理并到达Servlet之后,请求会被传递给DispatcherServlet。DispatcherServlet的主要职责是将请求分发给适当的处理器(如Controller方法)。
Spring MVC中拦截器的执行流程:
- 请求到达DispatcherServlet。
- DispatcherServlet根据请求获取处理器(Handler)和拦截器链(Interceptor Chain)。
- DispatcherServlet遍历拦截器链,依次执行拦截器的- preHandle方法。如果某个拦截器的- preHandle方法返回- false,则中止后续拦截器和处理器的执行,并立即返回响应。- preHandle方法通常用于执行请求预处理逻辑,例如身份验证和授权检查。
- 如果所有拦截器的preHandle方法都返回true,则DispatcherServlet执行处理器(Handler)来处理请求。
- 处理器处理完请求后,DispatcherServlet再次遍历拦截器链,按照相反的顺序依次执行拦截器的postHandle方法。postHandle方法在处理器执行之后、视图渲染之前调用,通常用于添加模型属性或对请求进行后处理。
- 最后,DispatcherServlet渲染视图并返回响应。
- 在请求处理完成并且视图渲染完成之后,DispatcherServlet再次遍历拦截器链,按照相反的顺序依次执行拦截器的afterCompletion方法。afterCompletion方法通常用于清理资源和记录日志等操作。
抽象拦截处理器(Handler)
public interface HandlerInterceptor {
    boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
    void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception;
    void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception;
}
处理器执行链(HandlerChain)
public class HandlerExecutionChain {
    private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);
     // 处理器对象
    private final Object handler;
    // 拦截器数组
    private HandlerInterceptor[] interceptors;
    // 拦截器列表
    private List<HandlerInterceptor> interceptorList;
    // 当前处理的拦截器索引
    private int interceptorIndex;
    public HandlerExecutionChain(Object handler) {
        this(handler, (HandlerInterceptor[]) null);
    }
    public HandlerExecutionChain(Object handler, HandlerInterceptor... interceptors) {
        this.interceptorIndex = -1;
        if (handler instanceof HandlerExecutionChain) {
            HandlerExecutionChain originalChain = (HandlerExecutionChain)handler;
            this.handler = originalChain.getHandler();
            this.interceptorList = new ArrayList();
            CollectionUtils.mergeArrayIntoCollection(originalChain.getInterceptors(), this.interceptorList);
            CollectionUtils.mergeArrayIntoCollection(interceptors, this.interceptorList);
        } else {
            this.handler = handler;
            this.interceptors = interceptors;
        }
    }
    public void addInterceptor(HandlerInterceptor interceptor) {
        this.initInterceptorList().add(interceptor);
    }
    public void addInterceptors(HandlerInterceptor... interceptors) {
        if (!ObjectUtils.isEmpty(interceptors)) {
            this.initInterceptorList().addAll(Arrays.asList(interceptors));
        }
    }
    private List<HandlerInterceptor> initInterceptorList() {
        if (this.interceptorList == null) {
            this.interceptorList = new ArrayList();
            if (this.interceptors != null) {
                this.interceptorList.addAll(Arrays.asList(this.interceptors));
            }
        }
        this.interceptors = null;
        return this.interceptorList;
    }
    public HandlerInterceptor[] getInterceptors() {
        if (this.interceptors == null && this.interceptorList != null) {
            this.interceptors = (HandlerInterceptor[])this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]);
        }
        return this.interceptors;
    }
		
  	// 执行拦截器链中的preHandle方法
    boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HandlerInterceptor[] interceptors = this.getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {
                HandlerInterceptor interceptor = interceptors[i];
                if (!interceptor.preHandle(request, response, this.handler)) {
                    this.triggerAfterCompletion(request, response, (Exception)null);
                    return false;
                }
            }
        }
        return true;
    }
  
  	// 执行拦截器链中的postHandle方法
    void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
        HandlerInterceptor[] interceptors = this.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);
            }
        }
    }
  
  	// 触发拦截器链中的afterCompletion方法
    void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception {
        HandlerInterceptor[] interceptors = this.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 var8) {
                    logger.error("HandlerInterceptor.afterCompletion threw exception", var8);
                }
            }
        }
    }
}
适用场景:
- 当程序需要使用不同方式处理不同种类请求, 而且请求类型和顺序预先未知时,可以使用责任链模式。
- 当必须按顺序执行多个处理者时,可以使用该模式。
- 如果所需处理者及其顺序必须在运行时进行改变,可以使用责任链模式。
以下是一些责任链设计模式的典型应用场景:
- 日志记录:不同级别的日志消息可以由不同的日志处理器处理,例如,DEBUG、INFO、WARNING和ERROR级别的日志分别由不同的处理器处理。
- 权限验证:根据用户的权限和角色对请求进行多层次的验证。例如,先验证用户身份,然后验证用户是否有访问特定资源的权限。
- 请求过滤:在Web应用中,可以使用责任链模式实现请求过滤器,对请求进行预处理(如身份验证、数据验证等)和后处理(如添加响应头、日志记录等)。
- 事件处理:在图形用户界面(GUI)中,事件可以由多个处理器处理,如按钮点击、键盘输入等。责任链模式可以实现事件处理的优先级和顺序。










![[C++]类与对象下篇](https://img-blog.csdnimg.cn/637abf9e1f1244ee9a48e6055b1bf957.png)








