取代OpenFeign:Spring Framework 6全新聲明式客戶端@HttpExchange

前言
Http是最常見的請(qǐng)求協(xié)議,每種編程語言都可發(fā)送Http請(qǐng)求。Java作為經(jīng)典編程語言之一,發(fā)送Http請(qǐng)求的客戶端更是不少,自己的內(nèi)置的就有java.net.HttpURLConnection以及Java 11以后的java.net.http.HttpClient。在Java 11之前,HttpURLConnection很難用,因此市場(chǎng)上百花齊放出現(xiàn)了不少優(yōu)秀的開源作品,典型代表為:
- Apache HttpClient(現(xiàn)最新為Http Component 5.x)
- OkHttp(現(xiàn)最新為OkHttp 4.x)
作為老牌的Apache HttpClient憑借著各種優(yōu)秀特征,似乎已成為了事實(shí)的標(biāo)準(zhǔn);后起之秀OkHttp不帶歷史包袱的輕裝上路,有著低網(wǎng)絡(luò)延遲、更優(yōu)秀的連接池性能,亦是一股不可輕視的力量。
Spring不到萬不得已之時(shí),一般不會(huì)自己重復(fù)造輪子。在Http客戶端這塊一樣借力打力,提供Http統(tǒng)一調(diào)用方式RestTemplate,屏蔽了細(xì)節(jié),規(guī)范了開發(fā)者的使用,簡(jiǎn)化了開發(fā)門檻。
PS:RestTemplate的底層實(shí)現(xiàn)依舊是Apache HttpClient、OkHttp、HttpURLConnection之一
以上,都還是編程式Http客戶端。隨著Spring Boot的普及,Spring Cloud的出現(xiàn),聲明式編碼變得越來越主流,因?yàn)槁暶魇?面向元數(shù)據(jù)編碼效率遠(yuǎn)高于編程式編碼效率。因此,F(xiàn)eign出現(xiàn)了,迅速成為了主流。
今年,隨著劃時(shí)代版本Spring Framework 6、Spring Boot 3、Spring Cloud 2022.0.0的發(fā)布,Spring團(tuán)隊(duì)自建了一套聲明式Http客戶端:@HttpExchange,目標(biāo)直指OpenFeign。
正文
全新的聲明式Http客戶端由Spring Framework 6提供定義,Spring Boot 3提供實(shí)現(xiàn),Spring Cloud 2022負(fù)責(zé)發(fā)揚(yáng)光大。今天我們就來體驗(yàn)一把
介紹一個(gè)免費(fèi)的、在線的Rest Http服務(wù)
由于我們需要一個(gè)提供Http Server來提供接口服務(wù),為此先給你介紹一個(gè)免費(fèi)的、24h在線的Rest Http服務(wù),省去我們自己搭建的麻煩。
地址:jsonplaceholder.typicode.com
每月提供近20億的請(qǐng)求,關(guān)鍵還是免費(fèi)的、可公開訪問的,好用得不要不要。

發(fā)一個(gè)簡(jiǎn)單的Http請(qǐng)求,就能獲取到數(shù)據(jù)。URL遵循Rest規(guī)范:

不挑Http或者Https,比如使用瀏覽器訪問這個(gè)URL得到的結(jié)果也是一樣的:

它提供多個(gè)Resources資源(以及多種Routes)供以訪問,對(duì)這些資源進(jìn)行增刪改查的操作,你想要的絕大部分都能滿足你。當(dāng)然,若你需要mock data是符合自己的數(shù)據(jù)結(jié)構(gòu)、業(yè)務(wù)邏輯的,可基于此項(xiàng)目做簡(jiǎn)單的修改即可,良心項(xiàng)目啊。具體詳情自行去官方體驗(yàn):https://jsonplaceholder.typicode.com。
全新聲明式Http客戶端@HttpExchange
環(huán)境聲明:Spring Boot 3.0.x
本文選用”albums“資源進(jìn)行測(cè)試:https://jsonplaceholder.typicode.com/albums的請(qǐng)求結(jié)果結(jié)構(gòu)如下:

Feign代碼示例
略!Feign的使用,相信大家再熟悉不過了,筆者這里就不費(fèi)周章。
@HttpExchange代碼示例
?????♀?按照albums的返回?cái)?shù)據(jù)結(jié)構(gòu),寫Java Bean:
順帶科普一個(gè)編碼規(guī)范:請(qǐng)求體Req中g(shù)et方法是必須的,set方法可選;響應(yīng)體Resp中set方法是必須的,get方法可選;二者都需遵循Java Bean規(guī)范! 粗暴的做法是不管需求如何,get/set一把梭,可行,但作為程序員的你應(yīng)該知道原由,理解要義。
?????♀?導(dǎo)入webflux包 此聲明式客戶端又Spring Framework 6提供,但由于其并未提供實(shí)現(xiàn)。Spring Boot 3為此提供了基于Reactive的Web實(shí)現(xiàn),因此需要導(dǎo)入webflux包:
?????♀?編寫Http客戶端申明式接口。
?????♀?書寫測(cè)試用例代碼。
?????♀?運(yùn)行測(cè)試代碼,控制臺(tái)輸出:
完美!
小細(xì)節(jié):創(chuàng)建的時(shí)候并未制定id,發(fā)現(xiàn)id是自增的(id=101)。但這并不會(huì)保存在typicode.com的遠(yuǎn)端服務(wù)器了,不會(huì)引起總條數(shù)的變化。
@HttpExchange聲明式客戶端簡(jiǎn)析
@HttpExchange是Spring Framework 6新提供的聲明式Http客戶端,客戶端的要素由注解的屬性 + 方法簽名來定義。先來看看這個(gè)注解:
和@RequestMapping參照對(duì)比:
不說一毛一樣,也是基本一樣。@HttpExchange注解可以標(biāo)注在類上和方法上,最終的URL組合起來生效。大家都是使用過Feign、使用過Spring MVC的,這就不用過多介紹了。
和@RequestMapping一樣,@HttpExchange也有其派生注解:
- @GetExchange:GET請(qǐng)求。類似于于@GetMapping
- @PostExchange:Post請(qǐng)求。類似于于@PostMapping
- @PutExchange:Put請(qǐng)求。類似于于@PutMapping
- @DeleteExchange:Delete請(qǐng)求。類似于于@DeleteMapping
- @PatchExchange:Patch請(qǐng)求。類似于于@PatchMapping
@HttpExchange聲明式客戶端前景展望
通過interface這種聲明式使用起來比RestTemplate,或者WebClient要簡(jiǎn)單很多,大大簡(jiǎn)化了開發(fā)步驟,對(duì)開發(fā)者更加友好。
最新發(fā)布的Spirng Cloud 2022.0.0里描述得很明白:停止對(duì)OpenFeign的特征支持。言外之意:OpenFeign即將被Spring Cloud“淘汰”,接棒的那必然是@HttpExchange嘍。所以在可預(yù)見的將來,前景一片大好。

但是,筆者認(rèn)為它還不夠成熟,主要有兩點(diǎn):
- 還不能支持Spring-Web的注解(@RequestMapping體系),若能支持個(gè)人覺得會(huì)更為方便。
- 目前還只有WebClient一套實(shí)現(xiàn)(由Spring Boot提供實(shí)現(xiàn)),而它屬于Reactive Web體系,也就是必須引入webFlux相關(guān)技術(shù),而webFlux在做業(yè)務(wù)開發(fā)時(shí)優(yōu)勢(shì)不明顯,并非主流。
- 因?yàn)槿鬢ebClient能從Reactive Web里剝離出來,筆者覺得就好很多了。
總結(jié)
誰能想到,OpenFeign竟然都快被淘汰了,Spring的大船滾滾向前,引領(lǐng)著整個(gè)潮流,逐漸暴露出了野心,或者說感受到了危機(jī)。
先抄襲,再超越,Spring做到了。隱藏在全新的聲明式客戶端背后,其實(shí)還有Spring Framework 6背后對(duì)Web Mapping體系的重構(gòu),細(xì)心的你或許已有所發(fā)現(xiàn)。這些話題、新發(fā)現(xiàn),留予筆者和你后續(xù)接著聊。




















