SOFA RPC源码解析之FilterChain

版权声明: https://blog.csdn.net/beyondself_77/article/details/80862185

1.SOFA RPC源码解析

1.1  FilterChain

        在SOFA RPC设计中,FilterChain是比较有新意的。它没有采用常用的List列表模式,即在List列表中存储Filter实现,然后按照Filter在列表中的顺序依次调用各Filter接口的filter方法,完成过滤器功能。

        FilterChain简化类图如下:


        首先,FilterChain实现了调用器com.alipay.sofa.rpc.invoke.Invoker接口;

        其次,Filter为抽象类,非单例模式,其子类需要实现invoke(FilterInvoker invoker, SofaRequest request)方法,实现具体的过滤功能。在此需要注意,invoke方法除了request参数外,还需要invoker方法,表示下一个Filter的调用对象,这点不同于常见的List列表实现方式。

        然后,引入新的FilterInvoker,该类实现了Invoker接口,为Filter的封装类,用作把过滤器包装成Invoker对象。另外,FilterInvoker采用链表节点设计方式,通过其构造函数FilterInvoker(Filter nextFilter, FilterInvoker invoker,AbstractInterfaceConfig config)可以看出,FilterInvoker包括两个主要属性:Filter类型的nextFilter,表示下一层过滤器;FilterInvoker类型的invoker,表示下一层Invoker。这种设计方式解耦了Filter和Service。同时,以FilterInvoker为链表节点,可以构造一个Filter执行链。

        再看一下FilterChain,它也有一个比较重要的属性:FilterInvoker类型的invokerChain,表示filter调用链的第一个节点,在FilterChain类的invoke方法中调用该节点的invoke方法,启动整个执行链。

        最后,看一下FilterChain的构造函数:

1.  protected FilterChain(List<Filter>filters, FilterInvoker lastInvoker, AbstractInterfaceConfig config) {
2.          // 调用过程外面包装多层自定义filter
3.          // 前面的过滤器在最外层
4.          invokerChain = lastInvoker;
5.          if (CommonUtils.isNotEmpty(filters)) {
6.              loadedFilters = newArrayList<Filter>();
7.              for (int i = filters.size() - 1; i >= 0;i--) {
8.                  try {
9.                      Filter filter = filters.get(i);
10.                     if(filter.needToLoad(invokerChain)) {
11.                         invokerChain = new FilterInvoker(filter,invokerChain, config);
12.                         // cache this forfilter when async respond
13.                         loadedFilters.add(filter);
14.                     }
15.                 } catch (Exception e) {
16.                     LOGGER.error("Errorwhen build filter chain", e);
17.                     throw newSofaRpcRuntimeException("Error when build filter chain", e);
18.                 }
19.             }
20.         }
21.     }

        FilterChain构造函数有三个参数:

        1.   filters:过滤器列表;

        2.   lastInvoker:最后一个调用器;

        3.   config:接口配置;

        从这段代码可以看出:

        首先,设置FilterChain的属性invokerChain为最后一个调用器lastInvoker;

        其次,倒序遍历过滤器列表filters,依次为每个filter做如下处理:

        1.   构造FilterInvoker,其参数依次为filter、invokerChain、config;

        2.   把invokerChain设置为新创建的FilterChain;

        当遍历完filters中所有的过滤器,FilterChain执行链也就创建完成。整个执行链的开始节点invokerChain为处于filters列表中第一位置的过滤器的FilterInvoker对象,最后一个节点为lastInvoker。

        这样,当调用FilterChain类invoke方法时,该方法调用invokerChain的invoke方法,启动整个执行链。依次调用执行链上每个节点FilterInvoker的invoke方法,完成整个执行链的过滤功能和服务功能。

1.      public SofaResponse invoke(SofaRequestrequest) throws SofaRpcException {
2.          if (nextFilter == null &&invoker == null) {
3.              throw newSofaRpcException(RpcErrorType.SERVER_FILTER, "Next filter or invoker isnull!");
4.          }
5.          return nextFilter == null ?
6.              invoker.invoke(request) :
7.              nextFilter.invoke(invoker,request);
8.      }

        每个节点FilterInvoker的invoke方法的执行流程如下:

        1.  如果该节点的nextFilter不为null,表示此节点为由过滤器封装成的Invoker对象,则调用nextFilter的invoke方法,参数为下一层调用器invoker和SOFA RPC请求。

        2.  如果该节点为nextFilter为null,表示此节点为最后一个调用器,则直接调用invoker的invoke方法。

猜你喜欢

转载自blog.csdn.net/beyondself_77/article/details/80862185