好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

完美解决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://HdhCmsTestw3.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入口:

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

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

结果看下图:

参考

经过查找资料,有文章提到是自动配置类的问题FeignAutoConfiguration,文章参考:HdhCmsTesttuohang.net/article/206294.htm文章提到,由于@ConditionalOnMissingBean({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冲掉,还好,在主类添加的@Bean创建的类正是在完成bean后再执行这里主类增加的@Bean创建的对象,所以最后加载过程中又会执行bean生命周期的finishBeanFactoryInitialization(beanFactory);

方法所在位置如下:

org . springframework . context . support . AbstractApplicationContext #finishBeanFactoryInitialization

注意事项

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

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

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

原文链接:https://blog.csdn.net/esunlang/article/details/113772887

查看更多关于完美解决SpringCloud-OpenFeign使用okhttp替换不生效问题的详细内容...

  阅读:35次