Feign源码解析之注入IOC容器
Feign源码解析之生成jdk动态代理
Feign源码解析之代理类的处理逻辑
上一篇文章讲解了在springcloud项目中feign代理类和feign方法的处理逻辑,在实际项目中,feign经常和hystrix一起使用。hystrix是一种熔断机制,当某个时间单位内错误次数达到一定比例,hystrix会认为服务出现故障,触发熔断,后续请求不再走该服务,防止引发系统错误的雪崩效应。当熔断时间错误后,hystrx会向对应服务尝试一次请求,判断服务是否恢复。
接下来我们看一下是用来hystrix后feign的代理类和处理逻辑和原来相比有哪些变化。
曾经在feign中是默认使用hystrix,虽然在后续的版本中改为了默认不使用hyxtrix,不过要想启用feign的hystrix,只需要增加配置feign.hystrix.enabled:true。另外提一点,可以通过@EnableHystrix或@EnableCircuitBreaker在整个项目中使用hystrix。
当feign中使用了hystrix,根据FeignClientsConfiguration的HystrixFeignConfiguration和FeignAutoConfiguration的HystrixFeignTargeterConfiguration可以看出,IOC容器中注入的Feign.Builder类和HystrixTargeter发生了变化。
@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();
}
}
@Configuration
@ConditionalOnClass(name = "feign.hystrix.HystrixFeign")
protected static class HystrixFeignTargeterConfiguration {
@Bean
@ConditionalOnMissingBean
public Targeter feignTargeter() {
return new HystrixTargeter();
}
}
从上一篇文章已经知道,Feign接口通过FeignClientFactoryBean的getObject方法委托targeter.target方法生成代理类,我们进行HystrixTargeter类的target方法。
@Override
public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context,
Target.HardCodedTarget<T> 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);
}
可以看出分4种情况:
1.非hyxtrix的feign