Spring Cloud与微服务构建(七)声明式调用Feign 7.5 在Feign中使用HttpClient和OkHttp

在Feign中,Client是一个非常重要的组件,Feign最终发送Request请求以及接收Response响应都是由Client组件完成的。Client在Feign源码中是一个接口,在默认的情况下,Client的实现类是Client。Default,Client.Default是由HttpURLConnection来实现网络请求的。另外Client还支持HttpClient和OkhHttp来进行网络请求。

首先查看FeignRibbonClient的自动配置类FeignRibbonClientutoConfiguration,该 类在工程启动时注入一些Bean,其中注入了一个BeanName为feignClient的Client类型的Bean,代码如下

@ConditionalOnClass({ILoadBalancer.class, Feign.class})
@Configuration
@AutoConfigureBefore({FeignAutoConfiguration.class})
public class FeignRibbonClientAutoConfiguration {
    public FeignRibbonClientAutoConfiguration() {
    }

    @Bean
    @Primary
    @ConditionalOnMissingClass({"org.springframework.retry.support.RetryTemplate"})
    public CachingSpringLoadBalancerFactory cachingLBClientFactory(SpringClientFactory factory) {
        return new CachingSpringLoadBalancerFactory(factory);
    }

    @Bean
    @Primary
    @ConditionalOnClass(
        name = {"org.springframework.retry.support.RetryTemplate"}
    )
    public CachingSpringLoadBalancerFactory retryabeCachingLBClientFactory(SpringClientFactory factory, LoadBalancedRetryPolicyFactory retryPolicyFactory) {
        return new CachingSpringLoadBalancerFactory(factory, retryPolicyFactory, true);
    }

    @Bean
    @ConditionalOnMissingBean
    public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory) {
        return new LoadBalancerFeignClient(new Default((SSLSocketFactory)null, (HostnameVerifier)null), cachingFactory, clientFactory);
    }

    @Bean
    @ConditionalOnMissingBean
    public Options feignRequestOptions() {
        return LoadBalancerFeignClient.DEFAULT_OPTIONS;
    }

    @Configuration
    @ConditionalOnClass({OkHttpClient.class})
    @ConditionalOnProperty(
        value = {"feign.okhttp.enabled"},
        matchIfMissing = true
    )
    protected static class OkHttpFeignLoadBalancedConfiguration {
        @Autowired(
            required = false
        )
        private okhttp3.OkHttpClient okHttpClient;

        protected OkHttpFeignLoadBalancedConfiguration() {
        }

        @Bean
        @ConditionalOnMissingBean({Client.class})
        public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory) {
            OkHttpClient delegate;
            if (this.okHttpClient != null) {
                delegate = new OkHttpClient(this.okHttpClient);
            } else {
                delegate = new OkHttpClient();
            }

            return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
        }
    }

    @Configuration
    @ConditionalOnClass({ApacheHttpClient.class})
    @ConditionalOnProperty(
        value = {"feign.httpclient.enabled"},
        matchIfMissing = true
    )
    protected static class HttpClientFeignLoadBalancedConfiguration {
        @Autowired(
            required = false
        )
        private HttpClient httpClient;

        protected HttpClientFeignLoadBalancedConfiguration() {
        }

        @Bean
        @ConditionalOnMissingBean({Client.class})
        public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory) {
            ApacheHttpClient delegate;
            if (this.httpClient != null) {
                delegate = new ApacheHttpClient(this.httpClient);
            } else {
                delegate = new ApacheHttpClient();
            }

            return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
        }
    }
}

在缺省配置BeanName为FeignClient的Bean的情况下,会自动注入Client.Default这个对象,跟踪client.default源码,client.default使用的网络请求框架为HttpURLConnection,代码如下:

        public Response execute(Request request, Options options) throws IOException {
            HttpURLConnection connection = this.convertAndSend(request, options);
            return this.convertResponse(connection).toBuilder().request(request).build();
        }

那么,如何在Feign中使用HttpClient的网络请求框架呢?下面继续查看FeignRibbonClientAutoConfiguration的源码:

    protected static class OkHttpFeignLoadBalancedConfiguration {
        @Autowired(
            required = false
        )
        private okhttp3.OkHttpClient okHttpClient;

        protected OkHttpFeignLoadBalancedConfiguration() {
        }

        @Bean
        @ConditionalOnMissingBean({Client.class})
        public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory, SpringClientFactory clientFactory) {
            OkHttpClient delegate;
            if (this.okHttpClient != null) {
                delegate = new OkHttpClient(this.okHttpClient);
            } else {
                delegate = new OkHttpClient();
            }

            return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
        }
    }

从代码@ConditionalOnClass(ApacheHttpClient.class)注解可知道,只需要在pom文件加上HttpClient的Classpath即可。另外需要在配置文件application.yml中配置feign.httpclient.enabled为true,从@ConditionalOnProperty注解可知,这个配置可以不写,因为在默认的情况下就为true。

在工程的pom文件加上feign-httpclient的依赖,Feign就会采用HttpClient作为网络请求框架,而不是默认的HttpURLConnection。代码如下“

<dependency>
	<groupId>com.netflix.feign</groupId>
	<artifactId>feign-httpclient</artifactId>
	<version>RELEASE</version>
</dependency>

同理,如果想要Feign中使用Okhttp作为网络请求框架,则只需要在pom文件上加上feign-okhttp的依赖,代码如下:

<dependency>
	<groupId>com.netflix.feign</groupId>
	<artifactId>feign-okhttp</artifactId>
	<version>RELEASE</version>
</dependency>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值