写点什么

Feign 的两个调用处理器

作者:周杰伦本人
  • 2022-10-20
    贵州
  • 本文字数:1868 字

    阅读完需:约 1 分钟

Feign 的两个调用处理器

feign 的调用处理器有默认的 FeignInvocationHandler


和 HystrixInvocationHandler,这篇文章我们将具体讲解一下这两个类

FeignInvocationHandler

Feign 远程调用的执行流程:调用 FeignInvocationHandler 的 invoke 方法


@Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {      if ("equals".equals(method.getName())) {        try {          Object              otherHandler =              args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;          return equals(otherHandler);        } catch (IllegalArgumentException e) {          return false;        }      } else if ("hashCode".equals(method.getName())) {        return hashCode();      } else if ("toString".equals(method.getName())) {        return toString();      }      return dispatch.get(method).invoke(args);    }
复制代码


这个方法中调用 SynchronousMethodHandler 方法处理器的 invoke 方法:dispatch.get(method).invoke(args);


SynchronousMethodHandler 的 invoke 方法中通过 RestTemplate 完成远程调用和获取调用的结果


FeignInvocationHandler 没有异常的熔断检测和恢复机制,也没有 Http 连接池。

HystrixInvocationHandler

HystrixInvocationHandler 的 invoke 方法创建 HystrixCommand 实例,HystrixCommand 的 getFallback()方法中调用 @FeignClient 注解中的 fallback 属性上指定的失败回退的类,执行业务回退的处理。


      @Override      protected Object getFallback() {        if (fallbackFactory == null) {          return super.getFallback();        }        try {          Object fallback = fallbackFactory.create(getExecutionException());          Object result = fallbackMethodMap.get(method).invoke(fallback, args);          if (isReturnsHystrixCommand(method)) {            return ((HystrixCommand) result).execute();          } else if (isReturnsObservable(method)) {            // Create a cold Observable            return ((Observable) result).toBlocking().first();          } else if (isReturnsSingle(method)) {            // Create a cold Observable as a Single            return ((Single) result).toObservable().toBlocking().first();          } else if (isReturnsCompletable(method)) {            ((Completable) result).await();            return null;          } else {            return result;          }        } catch (IllegalAccessException e) {          // shouldn't happen as method is public due to being an interface          throw new AssertionError(e);        } catch (InvocationTargetException e) {          // Exceptions on fallback are tossed by Hystrix          throw new AssertionError(e.getCause());        }      }
复制代码


Feign 的 JDK 动态代理实例是通过 Feign.Builder 的 target()方法完成,target 方法第一步是通过自身的 build()方法构造 RefectiveFeign 实例,然后调用 RefectiveFeign 的 newInstance()方法来创建真正的实例,对于 RefectiveFeign 的作用,我们上篇文章详细讲解了一下,这里就不再赘述了。

使用 HystrixFeign

在 FeignClientsConfiguration 类中我们可以看到 HystrixFeign 替代 feign.Feign 的条件


  @Configuration  @ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class })  protected static class HystrixFeignConfiguration {    @Bean    @Scope("prototype")    @ConditionalOnMissingBean    @ConditionalOnProperty(name = "feign.hystrix.enabled")    public Feign.Builder feignHystrixBuilder() {      return HystrixFeign.builder();    }  }
复制代码


类路径中有 HystrixCommand 类和 HystrixFeign 类,并且配置文件中有 feign.hystrix.enabled,满足这两个条件后就可以用 HystrixFeign 替代原来的 Feign

总结

这篇文章主要介绍了 Feign 的两个调用处理器,FeignInvocationHandler 和 HystrixInvocationHandler,FeignInvocationHandler 调用处理器没有异常的熔断机制和恢复机制,HystrixInvocationHandler 调用处理支持熔断和异常处理,getFallback()处理调用失败的业务处理,另外可以通过配置文件来配置 feign.hystrix.enabled 让 HystrixFeign 进行替代 feign.Feign

发布于: 刚刚阅读数: 4
用户头像

还未添加个人签名 2020-02-29 加入

公众号《盼盼小课堂》,多平台优质博主

评论

发布
暂无评论
Feign的两个调用处理器_10月月更_周杰伦本人_InfoQ写作社区