SpringCloud 之HttpClient、HttpURLConnection、OkHttpClient切换源码

承接上文,之前已经分析过OpenFegin 的创建、发送请求源码了,接下来,分析下底层的HttpClient、HttpURLConnection、OkHttpClient切换从源码级别来看是如何做到的。
在这里插入图片描述

Spring Cloud OpenFegin(创建、发送请求)源码

HttpClient、HttpURLConnection、OkHttpClient区别

  • HttpURLConnection:相当于原始JDBC操作,性能高,使用不方便
  • HttpClient:相当于 mybatis,基于JDBC封装了很多aip
  • OkHttpClient:加入了池化技术,可以复用连接

切换HttpClient 源码分析

我这里看的是 spring-cloud-starter-openfeign 2.2.9.RELEASE的源码,不同版本间的源码可能有些许差异。依赖如下

<!--        okhttp 以及 httpclient、fegin--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>2.2.9.RELEASE</version></dependency><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId><version>10.12</version></dependency><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId><version>10.12</version></dependency>

说句题外话,如下几处 fegin 的版本号要对应一下,不然就版本冲突了在这里插入图片描述
就 spring-cloud-starter-openfeign 2.2.9.RELEASE 来说,底层切换HttpClient作为网络通信框架很简单,项目中引入如下依赖,无需做任何配置,底层自动用HttpClient 去发送网络请求。接下来看源码。

<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId><version>10.12</version>
</dependency>

由于上文已经 debug 过 fegin 的全流程创建源码了,这里我直接贴入口,直接找到
org.springframework.cloud.openfeign.ribbon.HttpClientFeignLoadBalancedConfiguration这个类即可。如下图
在这里插入图片描述
可以看到 ApacheHttpClient 的生成条件如下,当我们项目中没有进行配置 feign.httpclient.enabled 时,默认被赋予成 true。所以要使用 ApacheHttpClient 的时候,加上依赖无需做任何配置就可以了。

@ConditionalOnClass({ApacheHttpClient.class}) 的意思是项目中必须存在ApacheHttpClient的 class,也就是必须导入对应的 maven 依赖

还有一个Import 注解,里面就是注册一些Bean定义信息。

@Configuration(proxyBeanMethods = false
)
@ConditionalOnClass({ApacheHttpClient.class})
@ConditionalOnProperty(value = {"feign.httpclient.enabled"},matchIfMissing = true
)
@Conditional({HttpClient5DisabledConditions.class})
@Import({HttpClientFeignConfiguration.class})

总结切换HttpClient源码

引入HttpClient 依赖后,开启HttpClient 无需配置 feign.httpclient.enabled,当我们要关闭Httpclient 时配置feign.httpclient.enabled = false。

feign:okhttp:enabled: truehttpclient:enabled: false

验证切换是否成功

fegin 的创建源码上文已经分析过了,这里直接贴结果。SpringCloud 所有的请求都是由 org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient进行发起的,具体的干活的被包装到 delegate 里面了,说实话当我看到这里的代码时候,想到了Mybatis 中的二级缓存的设计。委派模式。可以点击主页看我之前分析过的Mybatis 系列源码。通过下图可以看到当我发送一个请求的时候 delegate 是我们的 okHttpClient。说明已经切换 okHttpClient了
在这里插入图片描述

okHttpClient 切换源码分析

上文已经说过了所有请求都是通过 LoadBalancerFeignClient 这个入口过的。在org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient.的构造方法这打个断点,可以很清除的看到,当前项目用到的是什么 client。接下来分析okHttpClient的创建源码
在这里插入图片描述
通过分析注入条件我们可以知道,要开启 okHttpClient,必须配置 feign.okhttp.enabled = true,他不像开启httpClient 一样,条件注解上有 matchIfMissing = true(默认开启)。

@ConditionalOnClass({OkHttpClient.class}) 项目中必须存在 OkHttpClient 的类,也就是说必须导入OkHttpClient的 maven 依赖

@Configuration(proxyBeanMethods = false
)
@ConditionalOnClass({OkHttpClient.class})
@ConditionalOnProperty({"feign.okhttp.enabled"})
@Import({OkHttpFeignConfiguration.class})

总结 okHttpClient 切换源码

要开启 okHttpClient,必须配置 feign.okhttp.enabled = true,且添加对应的 maven 依赖,此时的 yaml 的配置如下

feign:okhttp:enabled: truehttpclient:enabled: false

同时开启 okHttp 与httpClient 会发生什么?

在这里插入图片描述
可以看到 httpClient 优先级高于 okHttp,至于原因的话,我没打算看了,估计就是几个条件注解互斥导致的,毕竟我看源码的目的就是为了,更好的熟悉各项配置的生效时机,以后碰到切换不生效的时候,打个断点调试一下就好了。
在这里插入图片描述

使用自定义okHttpClient

项目中自己注入okHttpClient就好了

package com.xxy.system.common.config;import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory;
import org.springframework.cloud.commons.httpclient.OkHttpClientFactory;
import org.springframework.cloud.openfeign.support.FeignHttpClientProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.TimeUnit;@Configuration
public class FeignConfig {@Bean@ConditionalOnMissingBean({ConnectionPool.class})public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties, OkHttpClientConnectionPoolFactory connectionPoolFactory) {Integer maxTotalConnections = httpClientProperties.getMaxConnections();Long timeToLive = httpClientProperties.getTimeToLive();TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);}@Beanpublic OkHttpClient client(OkHttpClientFactory httpClientFactory, ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) {Boolean followRedirects = httpClientProperties.isFollowRedirects();Integer connectTimeout = httpClientProperties.getConnectionTimeout();Boolean disableSslValidation = httpClientProperties.isDisableSslValidation();return httpClientFactory.createBuilder(disableSslValidation).connectTimeout((long) connectTimeout, TimeUnit.MILLISECONDS).followRedirects(followRedirects).connectionPool(connectionPool).readTimeout(666, TimeUnit.SECONDS)//.addInterceptor(new OkHttpLogInterceptor()) // 自定义请求日志拦截器.build();}
}

至于为什么自定义的 okHttpClient 会生效,看他的源码配置就好了org.springframework.cloud.openfeign.ribbon.OkHttpFeignLoadBalancedConfiguration。如下图,可以看到具体okHttpClient是通过构造方法入参自动注入的Bean。拿到的是IOC容器中我们自己的okHttpClient实例注入的,当我们的项目中没有显示的构造okHttpClient bean 时,里面会自动构造一个默认的okHttpClient。点到 OkHttpClient delegate = new OkHttpClient(okHttpClient); 这行代码里面看一下就好了。不多 bb。

在这里插入图片描述

同理注入 自定义 httpClient,项目中自己配置一个 httpClient 的 bean 即可,不多 bb

总结

个人在阅读fegin 源码的时候,打了比较多的断点,但是本文只贴关键断点源码。
在这里插入图片描述
关键断点

  1. org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient
    里面的构造器还有 execute 方法(校验配置是否生效断点)
  2. org.springframework.cloud.openfeign.ribbon.HttpClientFeignLoadBalancedConfiguration (httpClient版本的LoadBalancerFeignClient初始化断点)
  3. org.springframework.cloud.openfeign.ribbon.OkHttpFeignLoadBalancedConfiguration (okHttpClient版本的LoadBalancerFeignClient初始化断点)

这里是小咸鱼的技术窝欢迎拜访

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/612946.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在本地测试nginx中localhost不行,需要写成127.0.0.1

在Windows 10系统的命令提示符cmd中&#xff0c;执行命令ping localhost&#xff0c;并没有出现我与其的ip地址“127.0.0.1”&#xff0c;而是“[::1]”。 问题原因 在cmd中ping localhost解析出来的是ipv6的::1的原因是windows有个优先解析列表&#xff0c;当ipv6的优先级高于…

深度学习目标跟踪简述

深度学习目标跟踪是一个活跃的研究领域&#xff0c;它涉及使用深度学习技术来跟踪视频或实时摄像头中的对象。这个领域通常包括以下几个关键方面&#xff1a; 目标检测&#xff1a;在开始跟踪前&#xff0c;首先需要在视频的初始帧中检测到目标。这通常是通过卷积神经网络&…

基于ssm物流配送人员车辆调度管理系统的设计与实现+vue论文

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统物流配送人员车辆调度信息管理难度大&#xff0c;容错率低…

Thingsbaord采用redis缓存(自用)

在CentOS系统上&#xff0c;您可以通过以下步骤使用yum安装Redis&#xff1a; 添加EPEL仓库&#xff1a; 首先&#xff0c;需要添加EPEL&#xff08;Extra Packages for Enterprise Linux&#xff09;仓库&#xff0c;因为Redis可能不在默认的CentOS仓库中。使用以下命令添加EP…

【python】正则表达式-快速信息匹配,过滤与检测

前言 菜某的总结&#xff0c;希望能够帮到大家。 正则表达式的概念 简单来说就是匹配信息&#xff0c;创建一个规则&#xff0c;匹配文本中符合这个规则的内容 作用领域 单单看他的概念可能觉得他的用途也就是查找&#xff0c;实际上他的用途很广泛 1.信息筛选&#xff0c…

大语言模型面试问题

自己在看面经中遇到的一些面试题&#xff0c;结合自己和理解进行了一下整理。 transformer中求和与归一化中“求和”是什么意思&#xff1f; 求和的意思就是残差层求和&#xff0c;原本的等式为y H(x)转化为y x H(x)&#xff0c;这样做的目的是防止网络层数的加深而造成的梯…

如何创建自己的小程序?零编程一键创建实战指南

当今瞬息万变的数字世界中&#xff0c;拥有一个属于自己的小程序已成为企业与个人展示、服务和互动的重要途径。无需编码知识&#xff0c;通过便捷的云端可视化平台&#xff0c;也可以轻松创建一款符合自身需求且功能丰富的小程序。下面给大家分享如何创建自己的小程序。 1、选…

消息开始事件message start event

一&#xff1a;bpmn 二&#xff1a;java repositoryService.createDeployment().name("消息事件流程").addClasspathResource("bpmn/msg_event_process.bpmn").deploy(); identityService.setAuthenticatedUserId("huihui"); ProcessInstance p…

自适应批量生成二维码源码系统:电脑+手机端自适应 支持任何类型批量生成二维码 附带完整的搭建教程

在当今数字化的时代&#xff0c;二维码已经成为了我们日常生活和工作中的重要组成部分。无论是分享链接、添加好友&#xff0c;还是支付购物&#xff0c;二维码都以其便捷性受到了广泛的欢迎。下面&#xff0c;罗峰就来给大家分享一款自适应批量生成二维码源码系统&#xff0c;…

最新消息:OpenAI GPT Store 正式上线,GPTs 应用商店来了!

原文链接 https://openaigptguide.com/gpt-store-and-chatgpt-team/ OpenAI推出的两款新产品和服务&#xff1a;GPT Store和ChatGPT Team&#xff0c;提供了许多全新的解决方案和功能&#xff0c;旨在帮助用户更轻松地使用和构建GPT工具&#xff0c;同时也增加了公司的收入来源…

【JaveWeb教程】(17) MySQL数据库开发之 MySQL简介、安装、数据类型、SQL通用语法 详细代码示例讲解

目录 前言1. MySQL概述1.1 安装1.1.1 版本1.1.2 安装1.1.3 连接1.1.4 企业使用方式(了解) 1.2 数据模型1.3 SQL简介1.3.1 SQL通用语法1.3.2 分类 前言 在我们讲解SpringBootWeb基础知识(请求响应案例)的时候&#xff0c;我们讲到在web开发中&#xff0c;为了应用程序职责单一&…

Laravel 使用rdkafka_laravel详细教程(实操避坑)

一、选择rdkafka 首先要看版本兼容问题&#xff0c;我的是Laravel5.6&#xff0c;PHP是7.3.13&#xff0c;所以需要下载兼容此的rdkafka&#xff0c;去 Packagist 搜索 kafka &#xff0c;我用的是 Packagist选择里面0.10.5版本&#xff0c; 二、安装rdkafka 在 Laravel 项目…

python爬虫实战(9)--获取澎pai热榜

1. 需要的类包 import pandas as pd import requests2. 请求地址 通过分析&#xff0c;数据可以直接从接口获取&#xff0c;无需解析页面标签&#xff0c;直接取出我们需要的数据即可。 def fetch_hot_news(api_url):response requests.get(api_url)if response.status_cod…

[足式机器人]Part3 机构运动学与动力学分析与建模 Ch00-3(2) 刚体的位形 Configuration of Rigid Body

本文仅供学习使用&#xff0c;总结很多本现有讲述运动学或动力学书籍后的总结&#xff0c;从矢量的角度进行分析&#xff0c;方法比较传统&#xff0c;但更易理解&#xff0c;并且现有的看似抽象方法&#xff0c;两者本质上并无不同。 2024年底本人学位论文发表后方可摘抄 若有…

Vue+Element Ui实现el-table自定义表头下拉选择表头筛选

用vueelement ui开发管理系统时&#xff0c;使用el-table做表格&#xff0c;当表格列过多的时候&#xff0c;想要做成可选表头的&#xff0c;实现表格列的筛选显示&#xff0c;效果如下&#xff1a; 代码文件结构&#xff1a; 废话不多说&#xff0c;直接上代码&#xff1a; 第…

2023年,AI爆发的一年

公众号&#xff1a;算法一只狗 今年以来&#xff0c;AI呈爆发式发展。在文本生成的领域&#xff0c;涌现出以ChatGPT为代表的生成式大模型。而在文本图像生成方面&#xff0c;有高度自定义的Stable Diffusion&#xff0c;和简单易用上手的Midjournery。多模态领域更是百花齐放&…

外汇天眼:Options与OneTick合作,共同打造全球SAAS分析平台

Options Technology&#xff0c;一家为全球金融领域提供云服务的托管服务提供商&#xff0c;今天宣布与OneMarketData及其旗舰产品OneTick平台的合作。 Options将使OneTick订户能够访问其庞大的市场数据存储库&#xff0c;包括股票、外汇、期货、期权和固定收益数据&#xff0…

OpenAI GPT商店来了! 创业公司打不过就加入?|对话Agent创业公司S2R

文&#xff5c;郝 鑫 1月10日&#xff0c;OpenAI推出了在线商店“GPT Store”。该商店已于昨日开始向付费用户、团队和企业用户推出&#xff0c;商店汇集了用户为各种任务创建的ChatGPT的自定义版本。 2023年初到年末&#xff0c;Agent就像一位来自异域的吉普赛女郎&#…

linux 网络基础配置

将Linux主机接入到网络&#xff0c;需要配置网络相关设置一般包括如下内容&#xff1a; 主机名 iP/netmask (ip地址&#xff0c;网关) 路由&#xff1a;默认网关 网络连接状态 DNS服务器 &#xff08;主DNS服务器 次DNS服务器 第三个DNS服务器&#xff09; 一、…

【System Verilog and UVM实力进阶2】SVA语法

毛主席说过&#xff1a;没有调查就没有发言权。 《SVA介绍——学习SVA语法》系列第二讲 本文还是延续上一篇的风格&#xff0c;语言内容尽可能简单明了&#xff0c;有问题大家相互讨论&#xff0c;共同进步。需要电子书的朋友可以给我发邮件。tommi.weiqq.com 1.16 "ended…