当前位置: 首页 > news >正文

责任链模式解析FilterChain

分析:
过滤器链的调用过程
A过滤器调用chain.doFilter此时会进入到下一个过滤器
B过滤器继续调用chain.doFilter会继续进入下一个过滤器
当所有过滤器都执行完成后,会进入目标方法。
既然chain.doFilter能进入下一个过滤器,那本质上就是方法的调用压栈和弹栈,一个方法的调用入口会执行完成所有的方法栈后才完成。
所以chain内肯定知道下一个filter是哪个,同时chain肯定保存了最终的目标执行对象。
基于以上分析,chain内部维护了一个过滤器集合,并知道下一个过滤器是哪个。

运行结果:
    首先,任何编程语言在调用一个方法,都会层层调用多层方法栈。
     A
        B
            C
                D
                    E....
   其实,责任链设计模式无非就是通过代码解耦,将复杂的逻辑线性化。将一个一个的调用串行化。
   FilterChain将责任链的执行权交给每个过滤器,由过滤器决定是否执行下一个过滤器。
@Data
@Builder
public class HttpServletRequest {

    private String method;
    private String uri;

}
public class TargetController {

    public void target() {
        System.out.println("执行了最终的目标方法");
    }

}

public interface Filter {

    void doFilter(FilterChain filterChain, HttpServletRequest request) throws Exception;

}
public class AuthFilter implements Filter {

    @Override
    public void doFilter(FilterChain filterChain, HttpServletRequest request) throws Exception {
        System.out.println("auth filter before");
        filterChain.doFilter(request);
        System.out.println("auth filter after");
    }

}
public class LogFilter  implements Filter{
    @Override
    public void doFilter(FilterChain filterChain, HttpServletRequest request) throws Exception {
        System.out.println("log filter before ");
        filterChain.doFilter(request);
        System.out.println("log filter after ");
    }
}

@Data
@Builder
public class FilterChain {

    private Integer index;

    private List<Filter> filters;

    //执行最终目标方法的对象
    private Object target;

    //执行最终的目标方法
    private Method method;

    //执行最终目标方法的
    private Object[] args;


    public void doFilter(HttpServletRequest request) throws Exception {
        //获取当前要执行的过滤器
        if (index == null){
            index = 0;
        }
        if (filters == null || filters.size() <= 0){
            return;
        }
        if (index >= filters.size()){
            //执行最终的目标方法
            method.invoke(target,args);
            return;
        }
        //获取过滤器
        Filter filter = filters.get(index++);
        filter.doFilter(this,request);
    }

}
public class Test {

    public static void main(String[] args) throws Exception {

        FilterChain filterChain = FilterChain.builder()
                .filters(
                        Arrays.asList(new AuthFilter(), new LogFilter())
                )
                .index(0)
                .target(new TargetController())
                .method(TargetController.class.getMethod("target"))
                .args(null)
                .build();

        filterChain.doFilter(new HttpServletRequest("GET","/test"));

    }

}

相关文章:

  • 2000-2020年年汇率平均价数据
  • Ubuntu 22.04.5 LTS 安装企业微信,(2025-02-17安装可行)
  • 二十多年前的苹果电源Power Mac G4 Mdd 电源接口
  • 宝塔docker 安装oracle11G
  • 【097】基于51单片机排队叫号系统【Keil程序+报告+原理图】
  • 4.【线性代数】——矩阵的LU分解
  • STC 51单片机63——关于STC8H的ADC通道切换问题
  • 软硬链接?
  • 附录2:组维接口信息大全
  • 过于依赖chatgpt编程会有哪些弊端?
  • IOT-CVE-2018-17066(D-Link命令注入漏洞)
  • ubuntu22.04安装kvm、virt-manage并配置SR-IOV操作
  • Spring Boot 启动优化✨
  • TCP协议(Transmission Control Protocol)
  • Kubernetes控制平面组件:Kubernetes如何使用etcd
  • Python基础--计算机基础
  • 用于可靠工业通信的5G-TSN集成原型:基于帧复制与消除可靠性的研究
  • Pytorch使用手册-使用 PyTorch 和 TIAToolbox 进行全视野切片图像分类(专题十七)
  • 机器学习_18 K均值聚类知识点总结
  • el-tree选中数据重组成树
  • 阿里云的网站程序如何做/影视剪辑培训机构排名
  • 汕头企业网站建设服务/qq群排名优化软件官网
  • 百度网站建设微信封面/做网页的网站
  • dede网站名称不能中文/长沙市seo百度关键词
  • 南昌网站开发培训班/百度总部地址
  • 网站注册系统用什么做/交换友情链接的意义是什么