SpringCloud Feign扩展配置
SpringCloud Feign的流程介绍
@EnableFeignClients -> FeignClientsRegistrar 扫描 @Feign注解的类 -> FeignClientFactoryBean通过Targeter生产FeignClient -> Targeter通过Feign.Builder构建Feign -> Feign.Builder
- 准备工作(配置)
FeignAutoConfiguration自动配置类
@Configuration
@ConditionalOnClass(name = "feign.hystrix.HystrixFeign")
protected static class HystrixFeignTargeterConfiguration {
@Bean
@ConditionalOnMissingBean
public Targeter feignTargeter() {
return new HystrixTargeter();
}
}
@Configuration
@ConditionalOnMissingClass("feign.hystrix.HystrixFeign")
protected static class DefaultFeignTargeterConfiguration {
@Bean
@ConditionalOnMissingBean
public Targeter feignTargeter() {
return new DefaultTargeter();
}
}
feign.hystrix.HystrixFeign类存在时,将 HystrixTargeter 注册为 Targeter 类型的 bean
feign.hystrix.HystrixFeign类不存在时,使用 DefaultTargeter 。
看起来似乎可以使用自定义的Targeter代替Hystrix或默认的,这样就可以自定义各种功能了。实际上不行,因为 Targeter 是 package 访问级别的。
FeignClientsConfiguration
@Configuration
public class FeignClientsConfiguration {
@Bean
@ConditionalOnMissingBean
public Retryer feignRetryer() {
return Retryer.NEVER_RETRY;
}
@Bean
@Scope("prototype")
@ConditionalOnMissingBean
public Feign.Builder feignBuilder(Retryer retryer) {
return Feign.builder().retryer(retryer);
}
@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();
}
}
}
重要:Feign 以及内部类 Feign.Builder 都是 public 访问级别,可以注入自定义的bean。
2.EnableFeignClients与FeignClientsRegistrar类
将使用@FeignClient注解的类注册成spring bean,并使用注解中的配置
在@EnableFeignClients注解中导入FeignClientsRegistrar类
FeignClientsRegistrar类实现了ImportBeanDefinitionRegistrar类,会由spring框架执行实现方法 registerBeanDefinitions(AnnotationMetaData, BeanDefinitionRegistry)
FeignClientsRegistrar中的 registerBeanDefinitions方法调用两个方法
registerDefaultConfiguration:注册默认的配置
registerFeignClients:注册Feign客户端(重点)
registerFeignClients:获取 @EnableFeignClients注解中定义的配置扫描feign客户端
registerFeignClients:通过registerFeignClient(BeanDefinitionRegistry, AnnotationMetadata, Map)方法注册每一个feignClient,过程:先获取 @FeignClient注解中定义的配置,将配置应用在spring bean 工厂 FeignClientFactoryBean, 通过工厂类 FeignClientFactoryBean 为每一个使用@FeignClient注解的类生产 FeignClient,详细过程见下一节
3.FeignClientFactoryBean
FeignClient工厂bean。
class FeignClientFactoryBean
implements FactoryBean<Object>, InitializingBean, ApplicationContextAware{
//...
}
通过实现方法 FactoryBean#getObject()来由spring框架生产FeignClient。
@Override
public Object getObject() throws Exception {
return getTarget();
}
/**
* 获得目标
* 1. 获得FeignContext
* 2. 从FeignContext中获得Feign构建器Feign.Builder
* 3. 从FeignContext中获得Client,判断是否进行负载均衡
* 4. 从FeignContext中获得Target,并执行Target的默认方法target(FeignClientFactoryBean, Feign.Builder,
FeignContext, Target.HardCodedTarget<T>);
* 5.由于一开始注入的Feign.Buil