zoukankan      html  css  js  c++  java
  • Filter Pattern 2 (dubbo的实现方式)

    前一篇FilterPattern的范式,基本和Tomcat实现的filter chain是一样的;

    这里介绍一下我看完dubbo关于Filter Pattern的实现思路,自己抽象出来的代码,以及理解

    相关类的UML图:


    UML图


        可以从上图中看到这里的Invoker对应原来的Servlet,这里的Filter和原来的Filter只有参数签名上的区别;
    Filter的第一个参数由FilterChain变成了Invoker;
    Invoker和原来的Servlet的函数签名到是一点都没变,可以理解,只是名字不一样,功能性和原来一样(这里起名Invoker是为了和dubbo中的invoker保持一致)
    原先的Filter调用链路是有FilterChain来串联起来,现在FilterChain变成了Invoker,可以简单的猜想,现在由Invoker串起Filter调用链路;(这里你肯定想Invoker不是用来执行具体业务逻辑的吗,怎么能串的起Filter调用链路呢,具体可以往后看)

    至于是如何串起的,就要看FilterWrapper和相关Filter的代码了

    
    public class FilterWrapper {
    
        private List<Filter> filterList;
    
        public FilterWrapper(List<Filter> filterList) {
            this.filterList = filterList;
        }
    
        public Invoker buildInvokerChain(final Invoker invoker){
    
            Invoker last = invoker;
    
            //倒序遍历filterList,保证index最小的在最外层执行
            for (int i = filterList.size() - 1; i >= 0 ; i--) {
                final Invoker next = last;
    
                Filter filter = filterList.get(i);
                last = new Invoker() {
                    //用匿名内部类,把filter包装成invoker,为了方便理解,就没有写成lambda表达式了
                    @Override
                    public Response invoke(Request request) {
                        return filter.invoke(next, request);
                    }
                };
            }
    
            return last;
    
        }
    }
    
    
    public class PrintFilter implements Filter {
    
        @Override
        public Response invoke(Invoker invoker, Request request) {
    
            System.out.println("PrintFilter: request:" + request.getData());
    
            return invoker.invoke(request);
        }
    }
    
    
    public class ModifyDataFilter implements Filter {
    
        @Override
        public Response invoke(Invoker invoker, Request request) {
            request.setData(request.getData() + " modified by ModifyDataFilter!");
            return invoker.invoke(request);
        }
    }
    
    
    public class Main {
        public static void main(String[] args) {
            ArrayList<Filter> filterList = new ArrayList<>();
            filterList.add(new ModifyDataFilter());
            filterList.add(new PrintFilter());
    
            FilterWrapper filterWrapper = new FilterWrapper(filterList);
    
            Invoker invoker = filterWrapper.buildInvokerChain(new HttpInvoker());
    
            Request request = new Request("hello word!");
    
            Response response = invoker.invoke(request);
    
            System.out.println(response.getData());
    
        }
    }
    
    

        从上面的代码可以看到,实际上是用Invoker的匿名内部类来实现调用链路的串联,就我浅薄的理解,buildInvokerInvokerChain实现的invoker应该算是柯里化
    debug线程栈




    然而这样写Filter Chain有什么优点呢?

    1. Filter签名参数再也不用带着FilterChain了,Invoker接口单一,更加安全
  • 相关阅读:
    深入分析 Java 中的中文编码问题
    随便写写20160411
    Linux GDB 程序调试工具使用详解
    「美国花好几亿造出太空圆珠笔后,发现苏联航天员用铅笔」的故事真实吗?
    verynginx部署
    harbor私有仓库部署
    rancher学习
    harbor部署
    zabbix-proxy docker
    NFS部署
  • 原文地址:https://www.cnblogs.com/IC1101/p/15071394.html
Copyright © 2011-2022 走看看