Feign的构建过程及自定义扩展功能


spring-cloud-openfeign-core-2.1.1.RELEASE.jarHystrixFeign 的详细构建过程:

@EnableFeignClients -> FeignClientsRegistrar 扫描 @Feign注解的类 -> FeignClientFactoryBean通过Targeter生产FeignClient -> Targeter通过Feign.Builder构建Feign -> Feign.Builder

1. 准备工作(配置)

  1. 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();
		}

	}
  1. feign.hystrix.HystrixFeign类存在时,将 HystrixTargeter 注册为 Targeter 类型的 bean

  2. feign.hystrix.HystrixFeign类不存在时,使用 DefaultTargeter

  3. 看起来似乎可以使用自定义的Targeter代替Hystrix或默认的,这样就可以自定义各种功能了。实际上不行,因为 Targeterpackage 访问级别的。

  4. 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,并使用注解中的配置

  1. 在@EnableFeignClients注解中导入FeignClientsRegistrar类
  2. FeignClientsRegistrar类实现了ImportBeanDefinitionRegistrar类,会由spring框架执行实现方法 registerBeanDefinitions(AnnotationMetaData, BeanDefinitionRegistry)
  3. FeignClientsRegistrar中的 registerBeanDefinitions方法调用两个方法
    1. registerDefaultConfiguration:注册默认的配置
    2. registerFeignClients:注册Feign客户端(重点
  4. registerFeignClients:获取 @EnableFeignClients注解中定义的配置扫描feign客户端
  5. 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.Builder是HystrixFeign.Builder,则此处是调用HystrixFeign.Builder里的对应方法
 */
<T> T getTarget() {
   
    FeignContext context = this.applicationContext.getBean(FeignContext.class);
    Feign.Builder builder = feign(context);
    //省略部分代码
    // ......
    Client client = getOptional(context, Client.class);
	if (client != null) {
   
		if (client instanceof LoadBalancerFeignClient
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值