feign的Fallback机制
对接口使用@FeignClient后声明feign客户端后,可以使用属性fallback指定异常处理类,这个类必须实现@FeignClient作用的接口,且被注入到容器中。
@FeignClient(name = "service-provider1",fallback = NacosFeignImpl.class)public interface NacosFeignClient { @RequestMapping(value = "/echo/{str}",method = RequestMethod.GET) String echo(@PathVariable("str") String str);}@Componentpublic class NacosFeignImpl implements NacosFeignClient{ @Override public String echo(String str) { System.out.println("NacosFeignImpl#echo called"); return "echo error"; }}
添加配置项feign.hystrix.enabled=true
,当配置了HystrixFeign时,即会创建HystrixFeign.Builder。
// FeignClientsConfiguration.java@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();}}
在HystrixTargeter#target()发现使用了HystrixFeign.Builder并且属性fallback存在时,就会通过targetWithFallback()创建feign客户端。这里会到容器中获取实现了@FeignClient接口的Bean。
public T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context,Target.HardCodedTarget target) {if (!(feign instanceof feign.hystrix.HystrixFeign.Builder)) {return feign.target(target);}feign.hystrix.HystrixFeign.Builder builder = (feign.hystrix.HystrixFeign.Builder) feign;SetterFactory setterFactory = getOptional(factory.getName(), context,SetterFactory.class);if (setterFactory != null) {builder.setterFactory(setterFactory);}Class> fallback = factory.getFallback();if (fallback != void.class) {return targetWithFallback(factory.getName(), context, target, builder, fallback);}Class> fallbackFactory = factory.getFallbackFactory();if (fallbackFactory != void.class) {return targetWithFallbackFactory(factory.getName(), context, target, builder, fallbackFactory);}return feign.target(target);}
此时创建InvocationHandlerFactory,注入到属性invocationHandlerFactory,invocationHandlerFactory默认是InvocationHandlerFactory.Default
,这里重写create()方法,创建了HystrixInvocationHandler的实例对象。
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(); }
生成代理对象时,就会调用create()对HystrixInvocationHandler实例化,这样就会调用HystrixInvocationHandler#invoke()。
public T newInstance(Target target) { ...... InvocationHandler handler = factory.create(target, methodToHandler); T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(), new Class>[]{target.type()}, handler); for(DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) { defaultMethodHandler.bindTo(proxy); } return proxy; }
invoke()中run()的逻辑还是调用SynchronousMethodHandler#invoke()处理请求,发生异常时就会到getFallback()调用接口的实现类对象的方法。
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
来源地址:https://blog.csdn.net/weixin_42145727/article/details/128875925
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341