完美解决SpringCloud-OpenFeign使用okhttp替换不生效问题

 更新时间:2021年2月25日 15:00  
这篇文章主要介绍了完美解决SpringCloud-OpenFeign使用okhttp替换不生效问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

事发地

原默认的Feign是使用URLConnector进行通信的,当换为okhttp时,直接引入包及配置以下内容根本不生效,还是走原生的。

feign:
 okhttp:
 enable: true

事件还原

创建项目并引入pom相关的依赖如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <properties>
 <java.version>1.8</java.version>
 </properties>
 <dependencyManagement>
 <dependencies>
  <dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-dependencies</artifactId>
  <version>Finchley.RELEASE</version>
  <type>pom</type>
  <scope>import</scope>
  </dependency>
 </dependencies>
 </dependencyManagement>
<dependencies>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-test</artifactId>
 <scope>test</scope>
 </dependency>
</dependencies>

</project>``

启动类

@SpringBootApplication
@EnableFeignClients
public class Ch21OpenFeignApplication {

 public static void main(String[] args) {
 SpringApplication.run(Ch21OpenFeignApplication.class, args);
 }
}

配置文件

bootstrap.yml,这里只配置是否使用相关的HTTP

logging:
 level:
 springcloud.service.HelloFeignService: debug
feign:
 okhttp:
 enable: true
 httpclient:
 enable: false

测试类

Controller

.[email protected]
public class HelloFeignController {
 @Autowired
 private HelloFeignService helloFeignService;
 @RequestMapping(value = "/helloFeign",method = RequestMethod.GET)
 public Object helloFeign(){

 return helloFeignService.helloFeign();
 }
}`

service

@FeignClient(name = "feign-client",url = "http://localhost:8761",fallback = FallbackService.class)
public interface HelloFeignService {
 @RequestMapping(value = "/query/eureka-server",method = RequestMethod.GET)
 String helloFeign();
}

案件还原

写好上述的配置与类后,开始DEBUG,下图是Controller的DEBUG入口:

进入代理类查看HTTPCLIENT使用的是哪一个

到下图时就要注意了,这才是进入使用client的入口

结果看下图:

参考

经过查找资料,有文章提到是自动配置类的问题FeignAutoConfiguration,文章参考:www.jb51.net/article/206294.htm文章提到,[email protected]({okhttp3.OkHttpClient.class})导致了无法注入OkHttpClient

个人猜测

在只添加依赖包时,还没有自行创建okhttp相关的BEAN时,结果如下与添加了创建okhttp时一样。

启动springboot项目时,BEAN容器化时机不同导致得不到想要的client,在启动项目时,org.springframework.cloud.openfeign.FeignAutoConfiguration这个配置类是执行后。在BEAN装载时看到BEAN一级缓存如下图,并没有OKHTTP相关的信息。

在这个自动装配类最下方有一段代码根本没有执行,所以从始到终都没有看到有okHttpClient

@Bean
 @ConditionalOnMissingBean(Client.class)
 public Client feignClient() {
 return new OkHttpClient(this.okHttpClient);
 }

当我在主类添加以下代码时,得到的bean如下:

注意:feignClient 这个bean 是一个loadBalancerFeignClient

@Bean
 public okhttp3.OkHttpClient okHttpClient(){
 return new okhttp3.OkHttpClient.Builder()
  .readTimeout(60, TimeUnit.SECONDS)
  .connectTimeout(60, TimeUnit.SECONDS)
  .writeTimeout(120, TimeUnit.SECONDS)
  .connectionPool(new ConnectionPool())
  // .addInterceptor();
  .build();
 }

当我在主类再追加以下代码时,得到的bean如下:

注意:feignClient 这个bean,是我们要找的okhttp了

 @Bean
 @ConditionalOnMissingBean({Client.class})
 public Client feignClient(okhttp3.OkHttpClient client) {
 return new feign.okhttp.OkHttpClient(client);
 }

真正的真相

这个要再多看下创建流程,从代码上分析,这时在有new feign.okhttp.OkHttpClient(client); 这一段代码,重新把okhttp注入后,才使得feignClient 名称对应的bean为okhttp。不防从以下代码进行分析:

LoadBalancerFeignClient 的来源

如下图,LoadBalancerFeignClient是继承了Client,进入实现类feign.Client.Default,这个类全程都只有使用HttpURLConnection,所以无论怎样都只能获取到的是默认的JDK里的http的client

所以这个类创建后要想使用okhttp,那么就只能重新创建把旧的bean冲掉,还好,[email protected][email protected][email protected]eanFactoryInitialization(beanFactory);

方法所在位置如下:

org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization

注意事项

在主类添加的方法用来创建okhttp时,方法名一定要写成下图的这样,不然创建不了feignClient这个bean。

不知道是否有其他方法。这个估计是与org.springframework.cloud.openfeign.FeignAutoConfiguration.OkHttpFeignConfiguration#feignClient有关,相当于创建的方法是一个重写的过程。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。如有错误或未考虑完全的地方,望不吝赐教。

相关文章

  • 一篇文章教你如何在SpringCloud项目中使用OpenFeign

    这篇文章主要介绍了SpringCloud 使用Open feign 优化详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-08-16
  • 解决springcloud-gateway限流遇到的问题

    这篇文章主要介绍了解决springcloud-gateway限流遇到的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-16
  • SpringCloud如何解决服务之间的通信问题

    本文主要介绍了SpringCloud如何解决服务之间的通信问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-08-23
  • spring cloud gateway中如何读取请求参数

    这篇文章主要介绍了spring cloud gateway中如何读取请求参数的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-15
  • 解决SpringCloud Gateway配置自定义路由404的坑

    这篇文章主要介绍了解决SpringCloud Gateway配置自定义路由404的坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-02
  • Spring Cloud Config 使用本地配置文件方式

    这篇文章主要介绍了Spring Cloud Config 使用本地配置文件方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-16
  • Nginx+SpringCloud Gateway搭建项目访问环境

    本文主要介绍了Nginx+SpringCloud Gateway搭建项目访问环境,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-08-08
  • spring cloud如何集成nacos配置中心

    这篇文章主要介绍了spring cloud如何集成nacos配置中心操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-12
  • Spring Cloud 如何保证微服务内安全

    这篇文章主要介绍了Spring Cloud 如何保证微服务内安全的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-16
  • 使用springCloud+nacos集成seata1.3.0搭建过程

    这篇文章主要介绍了使用springCloud+nacos集成seata1.3.0搭建过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-08-22