0
点赞
收藏
分享

微信扫一扫

Feign的两个调用处理器

河南妞 2022-05-18 阅读 37

@[TOC]

大家好 我是周杰伦本人 欢迎关注我❤️

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()方法来创建真正的实例

使用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

举报

相关推荐

0 条评论