一起來學Spring Cloud(F版) | 第三篇:註解式HTTP請求Feign
Spring Cloud
為開發者提供了在分散式系統中的一些常用的元件(例如配置管理,服務發現,斷路器,智慧路由,微代理,控制匯流排,一次性令牌,全域性鎖定,決策競選,分散式會話叢集狀態)。使用Spring Cloud開發人員可以快速地完成實現這些模式的服務和應用程式。它們在任何分散式環境中都能很好地工作
Feign
註解式的Feign
使得 Java HTTP 客戶端編寫更方便。Feign
靈感來源於安卓網路程式設計框架Retrofit
、JAXRS-2.0
和Socket/">WebSocket
,支援可插拔編碼器和解碼器,降低 HTTP API 的複雜度,通過最少的資源和程式碼來實現和HTTP API
的連線。通過可定製的解碼器和錯誤處理,可以編寫任意的HTTP API。Spring Cloud Feign
封裝了Ribbon
這一元件,所以在使用Feign
同時還能提供負載均衡的功能,這一切只需要一個@FeignClient
即可完成。
早期版本的Feign
被Spring Cloud
團隊整合在spring-cloud-netflix
子專案下,但如今Spring Cloud
團隊將Spring Cloud Feign
獨立成一個單獨的spring-cloud-openfeign
專案
Try
準備三個工程,分別是eureka-server
、order-server
、product-server
Eureka Server
詳情參考第一章,或從文末的 GITHUB 連結獲取對應篇幅的完整程式碼
Product Server
一個普通的Eureka Client
即可,詳情參考上一章,或從文末的 GITHUB 連結獲取對應篇幅的完整程式碼
Order Server
這個例子也是在上一章的基礎之上做了擴充套件
依賴
對比上一章,此處多了一個spring-cloud-starter-openfeign
的依賴
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies>
配置檔案
在src/main/resources
目錄下建立一個bootstrap.yml
的檔案,寫上 eureka 相關配置資訊
server: port: 7072 spring: application: name: order-server eureka: instance: prefer-ip-address: true instance-id: ${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}} client: service-url: defaultZone: http://localhost:7071/eureka/
ProductClient 介面
建立一個ProductClient
,是不是感覺和XxxxService
看起來類似(用法都類似),都是介面檔案只不過在這個檔案的上方多了一個@FeignClient
註解,多種寫法,總有一款適合你
-
name
:指定FeignClient
的名稱,該屬性會作為微服務的名稱,用於服務發現 -
value
:同name
欄位互通 -
serviceId
:指定服務ID,每個註冊到註冊中心上的客戶端都會有對應的serviceId
一般是spring.application.name
,與name
和value
互通 -
url
: 一般用於除錯,可以指定一個詳細地址(ofollow,noindex">http://localhost:8080/products) -
path
: 請求統一路徑,可以看成@RequestMapping("/products")
-
decode404
:404 錯誤時,呼叫decoder
進行解碼,否則丟擲FeignException
-
fallback
:發生錯誤時,回撥hystrix
類/方法(後面會詳細介紹)
package com.battcn.api; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; /** * @author Levin * @since 2018/9/26 0026 */ @FeignClient(name = "product-server/products", decode404 = true) //@FeignClient(name = "products", url = "http://localhost:7073/products") //@FeignClient(value = "product", serviceId = "product-server", path = "/products", decode404 = true) public interface ProductClient { /** * 根據產品ID查詢產品資訊 * * @param productId ID * @return 查詢結果 */ @GetMapping("/{product_id}") String selectProductById(@PathVariable("product_id") Long productId); }
OrderController
直接使用@Autowired
注入進去即可,然後呼叫就好了,對比較Ribbon
這裡我們看不到RestTemplate
的程式碼了,也無需自己做解碼對映,Spring Cloud Feign
預設都替我們實現好了,我們只需要遵循既定的標準即可
package com.battcn.controller; import com.battcn.api.ProductClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author Levin * @since 2018/9/26 0026 */ @RestController @RequestMapping("/orders") public class OrderController { @Autowired private ProductClient productClient; @GetMapping public String query() { return this.productClient.selectProductById(10L); } }
主函式
通過@EnableFeignClients
註解開啟對Feign
的支援,用習慣Dubbo
的朋友喜歡將 API 打包成獨立的 JAR ,這個時候需要指定basePackage
屬性。
package com.battcn; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; /** * @author Levin */ @EnableFeignClients @EnableDiscoveryClient @SpringBootApplication public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
總結
目前很多大佬都寫過關於
Spring Cloud
的教程了,如有雷同,請多多包涵,本教程基於最新的spring-cloud:Finchley.SR1
編寫…