美文网首页
feignClient的实现原理(2)FeignClientFa

feignClient的实现原理(2)FeignClientFa

作者: 牧羊人刘俏 | 来源:发表于2019-11-21 18:50 被阅读0次

在FeignClientFactoryBean的<T> T getTarget()方法。

    <T> T getTarget() {

               //实例化Feign上下文对象FeignContext
        FeignContext context = applicationContext.getBean(FeignContext.class);
        Feign.Builder builder = feign(context);
               //如果没有执行url,使用负载均衡来生成调用客户端
        if (!StringUtils.hasText(this.url)) {
            String url;
            if (!this.name.startsWith("http")) {
                url = "http://" + this.name;
            }
            else {
                url = this.name;
            }
            url += cleanPath();
            return (T) loadBalance(builder, context, new HardCodedTarget<>(this.type,
                    this.name, url));
        }
               //不然的话直接的使用url来生成,这个功能在测试的时候非常的有效
        if (StringUtils.hasText(this.url) && !this.url.startsWith("http")) {
            this.url = "http://" + this.url;
        }
        String url = this.url + cleanPath();
        Client client = getOptional(context, Client.class);
        if (client != null) {
            if (client instanceof LoadBalancerFeignClient) {
                // not load balancing because we have a url,
                // but ribbon is on the classpath, so unwrap
                client = ((LoadBalancerFeignClient)client).getDelegate();
            }
            builder.client(client);
        }
        Targeter targeter = get(context, Targeter.class);
        return (T) targeter.target(this, builder, context, new HardCodedTarget<>(
                this.type, this.name, url));
    }

上面FeignContext context = applicationContext.getBean(FeignContext.class);
直接的在容器里面拿FeignContext的对象,那这个对象是什么时候用注册到spring的呢,
FeignAutoConfiguration配置类,里面的
@Autowired(required = false)
private List<FeignClientSpecification> configurations = new ArrayList<>();
直接拿到了我们在(一)里面讲的注册的FeignClientSpecification包括默认的和各个feignCliet配置的 configuration
然而,当我们引入了 sleuth之后,获取的 feignContext确是 TraceFeignClientAutoConfiguration中配置的实例 sleuthFeignContext:这是因为primary的配置导致的。
如下


image.png

那这个feignContext是在哪里初始化的呢。

@Configuration
@ConditionalOnClass(Feign.class)
@EnableConfigurationProperties({FeignClientProperties.class, FeignHttpClientProperties.class})
public class FeignAutoConfiguration {

    @Autowired(required = false)
    private List<FeignClientSpecification> configurations = new ArrayList<>();

    @Bean
    public HasFeatures feignFeature() {
        return HasFeatures.namedFeature("Feign", Feign.class);
    }

    @Bean
    public FeignContext feignContext() {
        FeignContext context = new FeignContext();
        context.setConfigurations(this.configurations);
        return context;
    }
}

我们看到FeignAutoConfiguration在里面有个FeignContext的bean,但是没有用这个bean,在代码里面看到通过FeignContextBeanPostProcessor接口将FeignContext的bean强转成了TraceFeignContext


image.png

相关文章

网友评论

      本文标题:feignClient的实现原理(2)FeignClientFa

      本文链接:https://www.haomeiwen.com/subject/lfutwctx.html