千家信息网

feign中的HystrixInvocationHandler作用是什么

发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,这篇文章主要讲解了"feign中的HystrixInvocationHandler作用是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"feign中
千家信息网最后更新 2025年01月23日feign中的HystrixInvocationHandler作用是什么

这篇文章主要讲解了"feign中的HystrixInvocationHandler作用是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"feign中的HystrixInvocationHandler作用是什么"吧!

本文主要研究一下feign的HystrixInvocationHandler

HystrixInvocationHandler

feign-hystrix-10.2.3-sources.jar!/feign/hystrix/HystrixInvocationHandler.java

final class HystrixInvocationHandler implements InvocationHandler {  private final Target target;  private final Map dispatch;  private final FallbackFactory fallbackFactory; // Nullable  private final Map fallbackMethodMap;  private final Map setterMethodMap;  HystrixInvocationHandler(Target target, Map dispatch,      SetterFactory setterFactory, FallbackFactory fallbackFactory) {    this.target = checkNotNull(target, "target");    this.dispatch = checkNotNull(dispatch, "dispatch");    this.fallbackFactory = fallbackFactory;    this.fallbackMethodMap = toFallbackMethod(dispatch);    this.setterMethodMap = toSetters(setterFactory, target, dispatch.keySet());  }  /**   * If the method param of InvocationHandler.invoke is not accessible, i.e in a package-private   * interface, the fallback call in hystrix command will fail cause of access restrictions. But   * methods in dispatch are copied methods. So setting access to dispatch method doesn't take   * effect to the method in InvocationHandler.invoke. Use map to store a copy of method to invoke   * the fallback to bypass this and reducing the count of reflection calls.   *   * @return cached methods map for fallback invoking   */  static Map toFallbackMethod(Map dispatch) {    Map result = new LinkedHashMap();    for (Method method : dispatch.keySet()) {      method.setAccessible(true);      result.put(method, method);    }    return result;  }  /**   * Process all methods in the target so that appropriate setters are created.   */  static Map toSetters(SetterFactory setterFactory,                                       Target target,                                       Set methods) {    Map result = new LinkedHashMap();    for (Method method : methods) {      method.setAccessible(true);      result.put(method, setterFactory.create(target, method));    }    return result;  }  @Override  public Object invoke(final Object proxy, final Method method, final Object[] args)      throws Throwable {    // early exit if the invoked method is from java.lang.Object    // code is the same as ReflectiveFeign.FeignInvocationHandler    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();    }    HystrixCommand hystrixCommand =        new HystrixCommand(setterMethodMap.get(method)) {          @Override          protected Object run() throws Exception {            try {              return HystrixInvocationHandler.this.dispatch.get(method).invoke(args);            } catch (Exception e) {              throw e;            } catch (Throwable t) {              throw (Error) t;            }          }          @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 if (isReturnsCompletableFuture(method)) {                return ((Future) result).get();              } else {                return result;              }            } catch (IllegalAccessException e) {              // shouldn't happen as method is public due to being an interface              throw new AssertionError(e);            } catch (InvocationTargetException | ExecutionException e) {              // Exceptions on fallback are tossed by Hystrix              throw new AssertionError(e.getCause());            } catch (InterruptedException e) {              // Exceptions on fallback are tossed by Hystrix              Thread.currentThread().interrupt();              throw new AssertionError(e.getCause());            }          }        };    if (Util.isDefault(method)) {      return hystrixCommand.execute();    } else if (isReturnsHystrixCommand(method)) {      return hystrixCommand;    } else if (isReturnsObservable(method)) {      // Create a cold Observable      return hystrixCommand.toObservable();    } else if (isReturnsSingle(method)) {      // Create a cold Observable as a Single      return hystrixCommand.toObservable().toSingle();    } else if (isReturnsCompletable(method)) {      return hystrixCommand.toObservable().toCompletable();    } else if (isReturnsCompletableFuture(method)) {      return new ObservableCompletableFuture<>(hystrixCommand);    }    return hystrixCommand.execute();  }  private boolean isReturnsCompletable(Method method) {    return Completable.class.isAssignableFrom(method.getReturnType());  }  private boolean isReturnsHystrixCommand(Method method) {    return HystrixCommand.class.isAssignableFrom(method.getReturnType());  }  private boolean isReturnsObservable(Method method) {    return Observable.class.isAssignableFrom(method.getReturnType());  }  private boolean isReturnsCompletableFuture(Method method) {    return CompletableFuture.class.isAssignableFrom(method.getReturnType());  }  private boolean isReturnsSingle(Method method) {    return Single.class.isAssignableFrom(method.getReturnType());  }  @Override  public boolean equals(Object obj) {    if (obj instanceof HystrixInvocationHandler) {      HystrixInvocationHandler other = (HystrixInvocationHandler) obj;      return target.equals(other.target);    }    return false;  }  @Override  public int hashCode() {    return target.hashCode();  }  @Override  public String toString() {    return target.toString();  }}
  • HystrixInvocationHandler实现了InvocationHandler接口,其构造器接收target、dispatch、setterFactory、fallbackFactory;invoke方法主要是创建hystrixCommand,然后执行hystrixCommand的execute或toObservable等方法;hystrixCommand的run方法执行HystrixInvocationHandler.this.dispatch.get(method).invoke(args),其getFallback方法主要是执行fallbackMethodMap.get(method).invoke(fallback, args)

InvocationHandlerFactory

feign-core-10.2.3-sources.jar!/feign/InvocationHandlerFactory.java

public interface InvocationHandlerFactory {  InvocationHandler create(Target target, Map dispatch);  /**   * Like {@link InvocationHandler#invoke(Object, java.lang.reflect.Method, Object[])}, except for a   * single method.   */  interface MethodHandler {    Object invoke(Object[] argv) throws Throwable;  }  static final class Default implements InvocationHandlerFactory {    @Override    public InvocationHandler create(Target target, Map dispatch) {      return new ReflectiveFeign.FeignInvocationHandler(target, dispatch);    }  }}
  • InvocationHandlerFactory接口定义了create方法用于创建InvocationHandler;它有一个Default的实现,其create方法创建的是ReflectiveFeign.FeignInvocationHandler

HystrixFeign

feign-hystrix-10.2.3-sources.jar!/feign/hystrix/HystrixFeign.java

public final class HystrixFeign {        //......  public static final class Builder extends Feign.Builder {    private Contract contract = new Contract.Default();    private SetterFactory setterFactory = new SetterFactory.Default();    //......    @Override    public Feign build() {      return build(null);    }    /** Configures components needed for hystrix integration. */    Feign build(final FallbackFactory nullableFallbackFactory) {      super.invocationHandlerFactory(new InvocationHandlerFactory() {        @Override        public InvocationHandler create(Target target,                                        Map dispatch) {          return new HystrixInvocationHandler(target, dispatch, setterFactory,              nullableFallbackFactory);        }      });      super.contract(new HystrixDelegatingContract(contract));      return super.build();    }    //......  }          //......}
  • HystrixFeign.Builder的build方法使用的InvocationHandlerFactory创建的是HystrixInvocationHandler

FeignClientsConfiguration

spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/FeignClientsConfiguration.java

@Configurationpublic class FeignClientsConfiguration {                //......        @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();                }        }        //......}
  • FeignClientsConfiguration的HystrixFeignConfiguration在有HystrixCommand.class, HystrixFeign.class以及feign.hystrix.enabled为true的情况下,其创建的Feign.Builder为HystrixFeign.builder

小结

HystrixInvocationHandler实现了InvocationHandler接口,其构造器接收target、dispatch、setterFactory、fallbackFactory;invoke方法主要是创建hystrixCommand,然后执行hystrixCommand的execute或toObservable等方法;hystrixCommand的run方法执行HystrixInvocationHandler.this.dispatch.get(method).invoke(args),其getFallback方法主要是执行fallbackMethodMap.get(method).invoke(fallback, args)

感谢各位的阅读,以上就是"feign中的HystrixInvocationHandler作用是什么"的内容了,经过本文的学习后,相信大家对feign中的HystrixInvocationHandler作用是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0