您好,登錄后才能下訂單哦!
這篇文章主要講解了“feign中的HystrixInvocationHandler作用是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“feign中的HystrixInvocationHandler作用是什么”吧!
本文主要研究一下feign的HystrixInvocationHandler
feign-hystrix-10.2.3-sources.jar!/feign/hystrix/HystrixInvocationHandler.java
final class HystrixInvocationHandler implements InvocationHandler { private final Target<?> target; private final Map<Method, MethodHandler> dispatch; private final FallbackFactory<?> fallbackFactory; // Nullable private final Map<Method, Method> fallbackMethodMap; private final Map<Method, Setter> setterMethodMap; HystrixInvocationHandler(Target<?> target, Map<Method, MethodHandler> 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<Method, Method> toFallbackMethod(Map<Method, MethodHandler> dispatch) { Map<Method, Method> result = new LinkedHashMap<Method, Method>(); 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<Method, Setter> toSetters(SetterFactory setterFactory, Target<?> target, Set<Method> methods) { Map<Method, Setter> result = new LinkedHashMap<Method, Setter>(); 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<Object> hystrixCommand = new HystrixCommand<Object>(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)
feign-core-10.2.3-sources.jar!/feign/InvocationHandlerFactory.java
public interface InvocationHandlerFactory { InvocationHandler create(Target target, Map<Method, MethodHandler> 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<Method, MethodHandler> dispatch) { return new ReflectiveFeign.FeignInvocationHandler(target, dispatch); } } }
InvocationHandlerFactory接口定義了create方法用于創建InvocationHandler;它有一個Default的實現,其create方法創建的是ReflectiveFeign.FeignInvocationHandler
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<Method, MethodHandler> dispatch) { return new HystrixInvocationHandler(target, dispatch, setterFactory, nullableFallbackFactory); } }); super.contract(new HystrixDelegatingContract(contract)); return super.build(); } //...... } //...... }
HystrixFeign.Builder的build方法使用的InvocationHandlerFactory創建的是HystrixInvocationHandler
spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/FeignClientsConfiguration.java
@Configuration public 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作用是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。