全部产品

自定义 Filter

更新时间:2020-07-24 15:57:03

SOFARPC 提供了一套良好的可扩展性机制,为各个模块提供 SPI(Service Provider Interface) 的能力。
SOFARPC 对请求与响应的过滤链(FilterChain)处理方式为:

  • 通过多个过滤器 Filter 来进行具体的拦截处理。
  • 允许用户自定义 Filter 扩展,且自定义 Filter 的执行顺序在内置 Filter 之后。

下文将就自定义 Filter 类及其生效进行说明:

自定义 Filter 类

自定义 Filter 类需继承 com.alipay.sofa.rpc.filter.Filter 类。示例如下:

展开查看自定义 Filter 类
  1. java
  2. package com.alipay.sofa.rpc.customfilter;
  3. import com.alipay.sofa.rpc.core.exception.SofaRpcException;
  4. import com.alipay.sofa.rpc.core.request.SofaRequest;
  5. import com.alipay.sofa.rpc.core.response.SofaResponse;
  6. import com.alipay.sofa.rpc.filter.Filter;
  7. import com.alipay.sofa.rpc.filter.FilterInvoker;
  8. import com.alipay.sofa.rpc.log.Logger;
  9. import com.alipay.sofa.rpc.log.LoggerFactory;
  10. public class CustomEchoFilter extends Filter {
  11. /**
  12. * Logger for CustomEchoFilter
  13. **/
  14. private static final Logger LOGGER = LoggerFactory.getLogger(CustomEchoFilter.class);
  15. @Override
  16. public boolean needToLoad(FilterInvoker invoker) {
  17. // 判断一些条件,自己决定是否加载这个 Filter
  18. return true;
  19. }
  20. @Override
  21. public SofaResponse invoke(FilterInvoker invoker, SofaRequest request) throws SofaRpcException {
  22. // 调用前打印请求
  23. LOGGER.info("echo request : {}, {}", request.getInterfaceName() + "." + request.getMethod(),
  24. request.getMethodArgs());
  25. // 继续调用
  26. SofaResponse response = invoker.invoke(request);
  27. // 调用后打印返回值
  28. if (response == null) {
  29. return response;
  30. } else if (response.isError()) {
  31. LOGGER.info("server rpc error: {}", response.getErrorMsg());
  32. } else {
  33. Object ret = response.getAppResponse();
  34. if (ret instanceof Throwable) {
  35. LOGGER.error("server biz error: {}", (Throwable) ret);
  36. } else {
  37. LOGGER.info("echo response : {}", response.getAppResponse());
  38. }
  39. }
  40. return response;
  41. }
  42. }

自定义 Filter 类生效方式

生效方式及示例,说明如下:

  • API 方式:该方式可以指定生效的 provider 或 consumer 。示例如下:
    展开查看 API 方式
    1. // 服务提供者
    2. providerConfig.setFilterRef(Arrays.asList(new CustomFilter()));
    3. // 服务调用者
    4. consumerConfig.setFilterRef(Arrays.asList(new CustomFilter()));

  • @Extension 注解 + 扩展文件 + 编码注入:见下述处理步骤。
    1. 处理自定义 Filter 类
      展开查看 Filter 类处理逻辑
      1. @Extension(“customer”)
        public class CustomFilter extends Filter {
        @Override
        public boolean needToLoad(FilterInvoker invoker) {
        return true;
        }
        @Override
        public SofaResponse invoke(FilterInvoker invoker, SofaRequest request) throws SofaRpcException {
        SofaResponse response = invoker.invoke(request);
        return response;
        }
        }
    2. 创建扩展文件
      • 文件名:以 Filter 为后缀。例如:com.alipay.sofa.rpc.filter.Filter
      • 文件路径:为固定路径。位于 META-INF/services/sofa-rpc/下。
      • 完整示例:META-INF/services/sofa-rpc/com.alipay.sofa.rpc.filter.Filter
        展开查看扩展文件内容
        1. customer=com.alipay.sofa.rpc.custom.CustomFilter
    3. 注入编码
      展开查看编码注入
      1. // 服务提供者
        providerConfig.setFilter(Arrays.asList(“customer”));
        // 服务调用者
        consumerConfig.setFilter(Arrays.asList(“customer”));
  • @Extension 注解 + 扩展文件 + @AutoActive 注解:见下述处理步骤。

    1. 处理自定义 Filter 类

      展开查看 Filter 类处理逻辑
      1. @Extension(“customer”)
        @AutoActive(providerSide = true, consumerSide = true)
        public class customerFilter extends Filter {
        @Override
        public boolean needToLoad(FilterInvoker invoker) {
        return true;
        }
        @Override
        public SofaResponse invoke(FilterInvoker invoker, SofaRequest request) throws SofaRpcException {
        SofaResponse response = invoker.invoke(request);
        return response;
        }
        }

      说明:使用 2 个注解 @Extension 和 @AutoActive 来处理 Filter 类,由此可以免去编码注入。作用域为所有 provider 或 consumer,其中参数 providerSide 表示是否生效于服务端,参数 consumerSide 表示是否生效于客户端。

    2. 创建扩展文件

      • 文件名:以 Filter 为后缀。例如:com.alipay.sofa.rpc.filter.Filter
      • 文件路径:固定路径。位于 META-INF/services/sofa-rpc/下。
      • 完整示例:META-INF/services/sofa-rpc/com.alipay.sofa.rpc.filter.Filter
        展开查看扩展文件内容
        1. customer=com.alipay.sofa.rpc.custom.CustomFilter