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

作者:esunlang 时间:2023-07-03 11:27:25 

事发地

原默认的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


.`@RestController
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入口:

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

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

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

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

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

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

结果看下图:

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

参考

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

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

个人猜测

在只添加依赖包时,还没有自行创建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);
}

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

当我在主类添加以下代码时,得到的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();
}

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

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

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


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

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

真正的真相

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

LoadBalancerFeignClient 的来源

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

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

所以这个类创建后要想使用okhttp,那么就只能重新创建把旧的bean冲掉,还好,在主类添加的@Bean创建的类正是在完成bean后再执行这里主类增加的@Bean创建的对象,所以最后加载过程中又会执行bean生命周期的finishBeanFactoryInitialization(beanFactory);

方法所在位置如下:


org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization

注意事项

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

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

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

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

来源:https://blog.csdn.net/esunlang/article/details/113772887

标签:SpringCloud,OpenFeign,okhttp
0
投稿

猜你喜欢

  • Android中TextView显示插入的图片实现方法

    2023-08-06 00:27:42
  • java编程多线程并发处理实例解析

    2022-06-02 22:14:59
  • Java 如何优雅的抛出业务异常

    2023-11-24 04:04:34
  • C++ 中String 替换指定字符串的实例详解

    2021-06-05 19:08:23
  • OpenCV实现人脸识别简单程序

    2023-07-07 00:31:12
  • Java面试题冲刺第十六天--消息队列

    2022-08-08 09:07:04
  • java 中Map详解及实例代码

    2023-06-06 01:27:37
  • C#使用Process类调用外部exe程序

    2023-02-12 16:54:20
  • Android启动页用户相关政策弹框的实现代码

    2021-06-30 15:29:30
  • springboot中PostMapping正常接收json参数后返回404问题

    2021-07-22 20:46:28
  • Java web实现账号单一登录,防止同一账号重复登录(踢人效果)

    2021-05-24 13:26:09
  • C#递归应用之实现JS文件的自动引用

    2023-12-09 00:03:52
  • Spring Cloud Ribbon客户端详细介绍

    2023-11-27 21:36:22
  • Android编程滑动效果之Gallery仿图像集浏览实现方法

    2022-11-19 15:21:58
  • 详解Android运行时权限及APP适配方法

    2021-06-15 11:06:17
  • Unity实现游戏卡牌滚动效果

    2023-09-20 10:54:23
  • Android SQLite数据库加密的操作方法

    2021-10-14 11:22:05
  • 事务在c#中的使用

    2021-11-27 23:30:29
  • Android实现连续点击多次事件的代码详解

    2022-02-09 23:28:28
  • 带着问题读CLR via C#(笔记二)类型基础

    2022-01-31 07:31:08
  • asp之家 软件编程 m.aspxhome.com