在項目中咱們有時候須要調用第三方的 API
,微服務架構中這種狀況則更是沒法避免——各個微服務之間通訊。好比通常的項目中,有時候咱們會使用 HTTP Client 發送 HTTP 請求來進行調用,而在微服務架構,Spring Cloud 全家桶中,Spring Cloud Feign 則是更常見的選擇。那麼,我如何只使用 Spring Cloud Feign 而不引入整個 Spring Cloud 呢?這就要從一個渣男語錄 API
提及了……java
API
呢?免費的 API
特別多,github
上也有免費 API
地址彙總的 repo
,但這些都太正式了。有趣的事物老是會相互吸引的,無心間我發現了這麼一個網站,「渣男:說話的藝術」(lovelive.tools/) ,每次請求均可以獲取一句甜言蜜語(渣男語錄),這不正是我這個鋼鐵直男須要的嗎?並且特別良心的是,做者提供了 API
列表,給做者點贊!git
首先,咱們先快速構建一個 Spring Boot 的 web 項目,這裏我就省略了。而後在咱們 gradle
文件中添加 spring-cloud-starter-openfeign
依賴:github
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-openfeign', version: '2.1.3.RELEASE' 複製代碼
而後,在啓動類添加響應的註解 @EnableFeignClients
:web
@SpringBootApplication @EnableFeignClients public class MyOpenFeignApplication { public static void main(String[] args) { SpringApplication.run(MyOpenFeignApplication.class, args); } } 複製代碼
接着,咱們即可以配置咱們的 Client 了,咱們先建立一個接口類,好比叫 BadGuyFeignClient
,並聲明爲 FeignClient
:spring
@FeignClient public interface BadGuyFeignClient { } 複製代碼
@FeignClient
有如下幾個較經常使用屬性:編程
name
,value
:指定 FeignClient
的名稱,若是項目使用了 Ribbon
,name
屬性會做爲微服務的名稱,用於服務發現;url
:url
通常用於調試,能夠手動指定 @FeignClient
調用的地址fallback
,fallbackFactory
:fallback
定義容錯的處理類,當調用遠程接口失敗或超時時,會調用對應接口的容錯邏輯,fallback
指定的類必須實現 @FeignClient
標記的接口;fallbackFactory
工廠類,用於生成 fallback
類示例,經過這個屬性咱們能夠實現每一個接口通用的容錯邏輯,減小重複的代碼;configuration
:Feign
配置類,能夠自定義 Feign
的 Encoder
、Decoder
、LogLevel
、Contract
;path
:定義當前 FeignClient
的統一前綴。而後,咱們即可以配置對應的屬性,這裏咱們只是用來實現相似於 HTTP Client 的功能,因此只是簡單配置了 url
和 path
這些屬性:api
@FeignClient(name = "badGuy", url = "${bab.guy.url}", path = "api") public interface BadGuyFeignClient { /** * 隨機獲取一句甜言蜜語 * * @return */ @GetMapping("SweetNothings") String getSweetNothings(); /** * 獲取 count 條甜言蜜語 * * @param count 獲取甜言蜜語條數 * @return Json 格式的結果 */ @GetMapping("SweetNothings/{count}/Serialization/Json") QuotationResult<String> getSweetNothingsJsonByCount(@PathVariable("count") Integer count); } 複製代碼
聲明爲 FeignClient
以後,咱們即可以在代碼中使用 @Resource
或者 @Autowire
進行注入使用了:markdown
@Component public class BadServiceImpl implements BadGuyService { @Autowired private BadGuyFeignClient badGuyFeignClient; @Override public List<String> getQuotations(Integer count) { if (count == null || count <= 0) { String singleQuotation = badGuyFeignClient.getSweetNothings(); return new ArrayList<String>() {{ add(singleQuotation); }}; } return badGuyFeignClient.getSweetNothingsJsonByCount(count).getReturnObj(); } } 複製代碼
而後 Controller
中是這麼寫的:架構
@GetMapping({"quotations", "quotations/{count}"}) public ResultWrapper<List<String>> getBadGuyQuotations( @PathVariable(value = "count", required = false) Integer count ) { try { List<String> resultStrings = badGuyService.getQuotations(count); return new ResultWrapper<>(resultStrings); } catch (Exception e) { log.error("Failed to get bad guy quotations.", e); return new ResultWrapper<List<String>>() {{ setCode("1000002"); setMessage("error"); setData(null); }}; } } 複製代碼
啓動項目以後,咱們能夠訪問 http://localhost:8088/api/badGuy/quotations 或者 http://localhost:8088/api/badGuy/quotations/10 後面跟數字,便可獲得對應條目數的結果。(完整項目地址在文末)app
FeignClient
與 HttpClient
的區別是什麼?HttpClient
與之一樣實現的還有 Okhttp
、Httpurlconnection
、RestTemplate
等等,其 URL 參數是以編程方式構造的,數據被髮送到其餘服務。在更復雜的狀況下,咱們將不得不RestTemplate
深刻到更低級別的 API
提供的甚至是 API
的細節。
FeignClient
則更像是在基於 REST 的服務調用上提供更高級別的抽象,在客戶端編寫聲明式 REST 服務接口,並使用這些接口來編寫客戶端程序。開發人員不用擔憂這個接口的實現。這將在運行時由 Spring 動態配置。經過這種聲明性的方法,開發人員不須要深刻了解由 HTTP 提供的 HTTP 級別 API
的細節的RestTemplate
。
總的來說,FeignClient
更具抽象性,也更簡單、靈活。
本文簡單介紹瞭如何使用 Spring Cloud Feign
組件來替代 HttpClient
來實現調用第三方服務的方法,除了集成 Feign
組件,咱們也能夠在項目中加入 Ribbon
用於服務發現,加入 Hystrix
用於服務熔斷等等,這樣就會完整地構建出一個基本服務了。
項目地址: github.com/lq920320/my…