设计模式之责任链模式

1. 责任链模式

1.1 责任链模式定义

当你想要让一个以上的对象 有机会能够处理某个请求的时候,就使用责任链模式

责任链模式为请求创建了一个接收者对象的链。执行链上有多个对象节点,每个对象节点都有机会(条件匹配)处理请求事务,如果某个对象节点处理完了,就可以根据实际业务需求传递给下一个节点继续处理或者返回处理完毕。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。

关键点

  • 解耦:请求的发送者不需要知道谁会处理这个请求,也不需要知道处理请求的具体过程。
  • 灵活性:可以在运行时动态地改变处理者链,使得系统更加灵活。
  • 可扩展性:可以轻松地向现有系统中添加新的处理者,而无需修改现有的代码。

结构

  • 抽象处理者(Handler) :定义了一个处理请求的接口,并且有一个指向其后续处理者的引用。

    具体处理者(Concrete Handler):实现抽象处理者的接口,根据实际情况决定是否处理请求或将其转发给下一个处理者。

  • 具体处理者(Concrete Handler):实现抽象处理者的接口,根据实际情况决定是否处理请求或将其转发给下一个处理者。

  • 客户端(Client):创建一个处理者链,并将请求提交给第一个处理者。

Spring AOP、Spring事务管理的一个重要特性是它使用了责任链模式;Spring MVC中的拦截器(Interceptor)等都用到了责任链模式。

1.2 责任链模式使用

责任链模式怎么使用呢?

  • 一个接口或者抽象类
  • 每个对象差异化处理
  • 对象链(数组)初始化(连起来)

1.3 具体代码

首先创建一个接口或者抽象类
java 复制代码
public abstract class AbstractHandler {

    /**
     * 责任链中的下一个对象
     */
    private AbstractHandler nextHandler;

    /**
     * 责任链的下一个对象
     */
    public void setNextHandler(AbstractHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    /**
     * 具体参数拦截逻辑,给子类去实现
     */
    public void filter(HttpServletRequest request, HttpServletResponse response) {
        doFilter(request, response);
        if (getNextHandler() != null) {
            getNextHandler().filter(request, response);
        }
    }

    public AbstractHandler getNextHandler() {
        return nextHandler;
    }

    /**
     * 抽象方法
     * @param filterRequest
     * @param response
     */
    abstract void doFilter(HttpServletRequest filterRequest, HttpServletResponse response);

}
每个对象差异化处理
java 复制代码
@Component
@Order(1)
public class CheckRequestHeaderFilterObject extends AbstractHandler {
    @Override
    void doFilter(HttpServletRequest filterRequest, HttpServletResponse response) {
        System.out.println("请求头校验");
    }
}
java 复制代码
@Component
@Order(2)
public class CheckCorsFilterObject extends AbstractHandler{
    @Override
    void doFilter(HttpServletRequest filterRequest, HttpServletResponse response) {
        System.out.println("cors校验");
    }
}
java 复制代码
@Component
@Order(3)
public class CheckParamFilterObject extends AbstractHandler{
    @Override
    void doFilter(HttpServletRequest filterRequest, HttpServletResponse response) {
        System.out.println("参数合法校验");
    }
}
java 复制代码
@Component
@Order(4)
public class CheckBlackFilterObject extends AbstractHandler{
    @Override
    void doFilter(HttpServletRequest filterRequest, HttpServletResponse response) {
        System.out.println("黑名单校验");
    }
}
对象链连起来(初始化)&& 使用
java 复制代码
@Component("ChainPatternTest")
public class ChainPatternTest {

    /**
     * 自动注入各个责任链的对象
     */
    @Resource
    private List<AbstractHandler> abstractHandleList;

    private AbstractHandler abstractHandler;

    /**
     * spring注入后自动执行,责任链的对象连接起来
     */
    @PostConstruct
    public void initializeChainFilter() {
        for (int i = 0; i < abstractHandleList.size(); i++) {
            if (i == 0) {
                abstractHandler = abstractHandleList.get(0);
            } else {
                AbstractHandler currentHandler = abstractHandleList.get(i - 1);
                AbstractHandler nextHandler = abstractHandleList.get(i);
                currentHandler.setNextHandler(nextHandler);
            }
        }
    }

    /**
     * 直接调用这个方法使用,根据实际使用来返回数据内容等
     *
     * @param request
     * @param response
     * @return
     */
    public HttpServletResponse exec(HttpServletRequest request, HttpServletResponse response) {
        abstractHandler.filter(request, response);
        return response;
    }

    public AbstractHandler getAbstractHandler() {
        return abstractHandler;
    }

    public void setAbstractHandler(AbstractHandler abstractHandler) {
        this.abstractHandler = abstractHandler;
    }
}

调用运行结果如下:

json 复制代码
请求头校验
cors校验
参数合法校验
黑名单校验
相关推荐
JH30737 小时前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
Coder_Boy_8 小时前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
invicinble9 小时前
对tomcat的提供的功能与底层拓扑结构与实现机制的理解
java·tomcat
较真的菜鸟9 小时前
使用ASM和agent监控属性变化
java
黎雁·泠崖9 小时前
【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理
java·开发语言
qq_124987075310 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
Coder_Boy_10 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
Mr_sun.10 小时前
Day06——权限认证-项目集成
java
瑶山10 小时前
Spring Cloud微服务搭建四、集成RocketMQ消息队列
java·spring cloud·微服务·rocketmq·dashboard
abluckyboy11 小时前
Java 实现求 n 的 n^n 次方的最后一位数字
java·python·算法