Feign的两个调用处理器
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
- 点赞
- 收藏
- 关注作者
评论(0)