- ?個人主頁:VON
- 文章所屬專欄:微服務
?
微服務系列文章
重生之我在暑假學習微服務第一天《MybatisPlus-上篇》 重生之我在暑假學習微服務第二天《MybatisPlus-下篇》 重生之我在暑假學習微服務第三天《Docker-上篇》 重生之我在暑假學習微服務第四天《Docker-下篇》 重生之我在暑假學習微服務第五天《Docker部署項目篇》 重生之我在暑假學習微服務第六天《微服務之拆分項目篇》 重生之我在暑假學習微服務第七天《微服務之服務治理篇》 未完待續....
特別聲明:本系列所涉及資料皆為黑馬程序員課程中的資料
目錄
?一、認識OpenFeign
1、引入依賴
?2、在啟動類中引入注解?編輯
3、編寫客戶端
4、開始調用
二、實現原理
1. 核心組件與工作流程
(1)接口掃描與代理生成
(2)方法注解解析
(3)HTTP 請求構建與發送
(4)響應處理與結果轉換
2. 關鍵組件詳解
三、利用連接池來進行優化
1、引入依賴
2、修改yaml文件
四、最佳使用方式
1、創建hm-api模塊
?2、改造hm-api模塊
?3、在cart模塊引入api依賴
4、修改啟動類?
5、測試
五、日志
結語
?
?一、認識OpenFeign
不知道昨天的大家學習的如何了,今天和昨天學的東西大致一致,就是利用新技術(OpenFeign )來簡化我們的代碼。
OpenFeign 是一個聲明式的 HTTP 客戶端框架,主要用于簡化 RESTful API 的調用。它通過注解和接口定義的方式,讓開發者能夠以更簡潔的方式編寫 HTTP 請求邏輯,而無需手動處理底層的 HTTP 通信細節。
1、引入依賴
<!-- openfeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
<!-- 負載均衡器--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
?2、在啟動類中引入注解
3、編寫客戶端
4、開始調用
先導入
?這樣就直接將上面這一段簡化成了一行代碼
啟動成功!!!?
?
二、實現原理
┌─────────────────┐ 啟動時掃描 ┌───────────────────────────────┐
│ @EnableFeignClients ────────→ 掃描@FeignClient標記的接口 │
└─────────────────┘ └──────────────┬────────────────┘│
┌─────────────────┐ 生成動態代理 ┌────────────▼────────────────┐
│ Spring容器注冊 ←────────────── 為接口創建JDK動態代理對象 │
└────────┬────────┘ └───────────────────────────────┘│
┌────────▼────────┐ 調用接口方法 ┌───────────────────────────────┐
│ 業務代碼注入接口 ───────────────→ 觸發動態代理的invoke方法 │
└─────────────────┘ └────────────┬────────────────┘│
┌────────────────────────────────────────────▼─────────────────────────┐
│ 解析請求信息 │
│ 1. 解析@FeignClient的服務名、@GetMapping等注解的HTTP方法/路徑 │
│ 2. 提取方法參數(@PathVariable/@RequestParam等) │
│ 3. 拼接基礎URL(服務名 + 接口路徑) │
└────────────────────────────────────┬─────────────────────────────────┘│
┌────────────────────────────────────▼─────────────────────────────────┐
│ 服務地址解析 │
│ 1. 若集成服務發現(Eureka/Nacos),通過服務名獲取實例列表 │
│ 2. 若集成負載均衡(Ribbon),選擇具體服務實例(如輪詢/隨機策略) │
│ 3. 生成最終請求地址(如http://192.168.1.100:8080/users/1) │
└────────────────────────────────────┬─────────────────────────────────┘│
┌────────────────────────────────────▼─────────────────────────────────┐
│ 構建HTTP請求 │
│ 1. Encoder將請求參數序列化(如JSON) │
│ 2. 組裝請求頭(默認頭 + 自定義Interceptor添加的頭) │
│ 3. 構建完整請求對象(Method/URL/Body/Headers) │
└────────────────────────────────────┬─────────────────────────────────┘│
┌────────────────────────────────────▼─────────────────────────────────┐
│ 發送HTTP請求 │
│ 1. 通過Client組件(默認HttpURLConnection,可替換為OkHttp)發送請求 │
│ 2. 若配置Retryer,失敗時執行重試邏輯 │
└────────────────────────────────────┬─────────────────────────────────┘│
┌────────────────────────────────────▼─────────────────────────────────┐
│ 處理響應結果 │
│ 1. 接收響應(狀態碼/響應體) │
│ 2. 若狀態碼非2xx,拋出FeignException(或觸發fallback) │
│ 3. Decoder將響應體反序列化為返回值對象(如User) │
└────────────────────────────────────┬─────────────────────────────────┘│
┌─────────────────┐ 返回結果 ┌─────▼───────────┐
│ 業務代碼接收結果 ←────────── 動態代理返回數據 │
└─────────────────┘ └─────────────────┘
1. 核心組件與工作流程
OpenFeign 的工作流程可分為四個關鍵步驟:
(1)接口掃描與代理生成
- 啟動時掃描:通過?
@EnableFeignClients
?注解觸發掃描,Spring 會掃描指定包下所有被?@FeignClient
?注解標記的接口。 - 動態代理創建:對每個?
@FeignClient
?接口,OpenFeign 會通過?Feign.Builder
?創建一個動態代理對象(JDK 動態代理),并將其注冊到 Spring 容器中。- 后續業務代碼中注入該接口時,實際使用的是這個代理對象。
(2)方法注解解析
當調用代理對象的接口方法時,代理會觸發以下操作:
- 解析注解信息:解析方法上的?
@RequestMapping
、@GetMapping
、@PostMapping
?等注解,提取 HTTP 方法(GET/POST 等)、URL 路徑、請求參數、請求頭等信息。 - 拼接請求 URL:結合?
@FeignClient
?中的?value
(服務名)和方法上的路徑,生成完整的請求 URL(如?http://服務名/路徑
)。- 服務名會通過服務發現(如 Eureka、Nacos)轉換為實際的服務地址。
(3)HTTP 請求構建與發送
- 構建請求:根據解析到的信息,OpenFeign 會構建一個 HTTP 請求對象(包含 URL、方法、參數、header 等)。
- 執行請求:通過內部的?
Client
?組件發送 HTTP 請求。默認使用 JDK 原生的?HttpURLConnection
,也可配置為 OkHttp、Apache HttpClient 等。- 若集成了負載均衡(如 Ribbon、Spring Cloud LoadBalancer),會先通過負載均衡策略選擇具體服務實例的地址。
(4)響應處理與結果轉換
- 接收響應:Client 組件接收 HTTP 響應,解析響應狀態碼、響應體等。
- 結果轉換:根據接口方法的返回值類型,將響應體轉換為對應的 Java 對象(默認使用 Jackson 進行 JSON 反序列化)。
- 異常處理:若響應狀態碼非 2xx,會根據配置拋出對應的異常(如?
FeignException
)。
2. 關鍵組件詳解
FeignClient
?注解:標記接口為 Feign 客戶端,包含服務名、URL、 fallback 等配置。Contract
:定義注解 解析規則,默認支持 Spring MVC 的注解(如?@RequestMapping
),也可自定義。Encoder/Decoder
:Encoder
:將請求參數對象轉換為 HTTP 請求體(如 JSON 序列化)。Decoder
:將 HTTP 響應體轉換為接口方法的返回值對象。
Client
:實際執行 HTTP 請求的組件,可替換為 OkHttp、HttpClient 等。Retryer
:請求失敗時的重試策略,默認不重試,可自定義重試邏輯。Interceptor
:請求 / 響應攔截器,可用于統一添加 header、日志打印等。
OpenFeign 的核心是通過動態代理將接口方法調用映射為 HTTP 請求,其實現依賴于:
- 注解解析提取請求信息;
- 動態代理生成接口實現類;
- 可擴展的 HTTP 客戶端發送請求;
- 序列化 / 反序列化處理數據轉換。
三、利用連接池來進行優化
1、引入依賴
2、修改yaml文件
直接在最后添加即可
四、最佳使用方式
1、創建hm-api模塊
引入相關依賴
?2、改造hm-api模塊
將cart服務中的Item相關的都剪切過來
?3、在cart模塊引入api依賴
4、修改啟動類?
?最后修改下啟動類使得他們能夠連接起來
5、測試
可以看到數據正常顯示,修改成功!
五、日志
可以看到我們這里發起請求的時候并沒有日志
先添加一個類來存儲日志級別
在啟動類中應用一下?
重新啟動項目發起請求查看日志,可以看到這里的日志十分完整了?
結語
本文介紹了微服務開發中使用OpenFeign的技術要點。主要內容包括:1)OpenFeign的基本使用,通過聲明式接口簡化HTTP調用;2)核心原理分析,包括動態代理生成、注解解析、請求構建和響應處理流程;3)優化實踐,如引入連接池提高性能;4)最佳使用方式,通過api模塊統一管理服務接口;5)日志配置方法,便于調試監控。文章結合具體代碼示例,詳細講解了如何利用OpenFeign簡化微服務間的遠程調用,并給出了性能優化和規范使用的建議。
?
?
?