Spring Cloud OpenFeign簡介
1.概述
在本教程中,我們將描述Spring Cloud OpenFeign –用於Spring Boot應用程序的聲明式REST客戶端。
Feign通過可插入註釋支持(包括Feign註釋和JAX-RS註釋)使編寫Web服務客戶端更加容易。
而且,Spring Cloud添加了對Spring MVC註釋的支持,並支持使用與Spring Web中使用的相同的HttpMessageConverters
。
使用Feign的一大好處是,除了接口定義外,我們無需編寫任何代碼來調用服務。
2. 依賴關係
首先,我們將創建一個Spring Boot Web項目並將spring-cloud-starter-openfeign
依賴項添加到我們的pom.xml
文件中:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
另外,我們需要添加spring-cloud-dependencies
:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
我們可以在Maven Central上找到[spring-cloud-starter-openfeign](https://search.maven.org/search?q=g:org.springframework.cloud%20AND%20a:spring-cloud-starter-openfeign)
和spring-cloud-dependencies
的最新版本。
3. Feign客戶端
接下來,我們需要在主類中添加@EnableFeignClients
:
@SpringBootApplication
@EnableFeignClients
public class ExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
}
使用此註釋,我們可以對組件聲明為Feign客戶端的接口啟用組件掃描。
然後,我們使用@FeignClient
批註聲明一個Feign客戶:
@FeignClient(value = "jplaceholder", url = "https://jsonplaceholder.typicode.com/")
public interface JSONPlaceHolderClient {
@RequestMapping(method = RequestMethod.GET, value = "/posts")
List<Post> getPosts();
@RequestMapping(method = RequestMethod.GET, value = "/posts/{postId}", produces = "application/json")
Post getPostById(@PathVariable("postId") Long postId);
}
在此示例中,我們配置了一個客戶端以從JSONPlaceHolder API讀取。
@FeignClient
批註中傳遞的value參數是強制性的任意客戶端名稱,而使用url
參數時,我們指定API基本URL。
此外,由於此接口是Feign客戶端,因此我們可以使用Spring Web批註來聲明我們想要聯繫的API。
4.配置
現在,了解每個Feign客戶端由一組可自定義的組件組成非常重要。
Spring Cloud使用我們可以自定義的FeignClientsConfiguration
類根據需要為每個命名客戶端創建一個新的默認集,如下一節所述。
上面的類包含以下bean:
- Decoder –
ResponseEntityDecoder
,包裝SpringDecoder,
用於解碼Response
- 編碼器–
SpringEncoder
,用於編碼RequestBody
- 記錄器–
Slf4jLogger
是Feign使用的默認記錄器 - 合同–
SpringMvcContract
,提供註釋處理 - Feign-Builder –
HystrixFeign.Builder
用於構造組件 - 客戶端–
LoadBalancerFeignClient
或默認的Feign客戶端
4.1。自定義Bean配置
如果要自定義一個或多個這些bean,可以使用@Configuration
類覆蓋它們,然後將其添加到FeignClient
批註中:
@FeignClient(value = "jplaceholder",
url = "https://jsonplaceholder.typicode.com/",
configuration = MyClientConfiguration.class)
@Configuration
public class MyClientConfiguration {
@Bean
public OkHttpClient client() {
return new OkHttpClient();
}
}
在此示例中,我們告訴Feign使用OkHttpClient
而不是默認值來支持HTTP / 2。
Feign支持針對不同用例的多個客戶端,包括ApacheHttpClient
,該客戶端隨請求發送更多的標頭,例如某些服務器期望的Content-Length,
。
要使用這些客戶端,請不要忘記將所需的依賴項添加到我們的pom.xml
文件中,例如:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
我們可以在Maven Central上找到最新版本的feign-okhttp
和feign-okhttp
feign-httpclient
。
4.2。使用屬性進行配置
無需使用@Configuration
類,我們可以使用應用程序屬性來配置Feign客戶端,如以下application.yaml
示例所示:
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 5000
loggerLevel: basic
使用此配置,我們將應用程序中每個聲明的客戶端的超時設置為5秒,記錄器級別設置為basic
。
最後,我們可以使用default
名稱作為客戶端名稱來創建配置,以配置所有@FeignClient
對象,或者我們可以為配置聲明@FeignClient
客戶端名稱:
feign:
client:
config:
jplaceholder:
如果我們同時具有@Configuration
bean和配置屬性,則配置屬性將覆蓋@Configuration
值。
5.攔截器
Feign提供的另一個有用的功能是攔截器。
攔截器可以為每個HTTP請求/響應執行從身份驗證到日誌記錄的各種隱式任務。
在本節中,我們將實現自己的攔截器,並使用現成的Spring Cloud OpenFeign提供的攔截器。兩者都將向每個請求添加基本身份驗證標頭。
5.1。實現RequestInterceptor
因此,在下面的代碼段中,讓我們實現自定義請求攔截器:
@Bean
public RequestInterceptor requestInterceptor() {
return requestTemplate -> {
requestTemplate.header("user", username);
requestTemplate.header("password", password);
requestTemplate.header("Accept", ContentType.APPLICATION_JSON.getMimeType());
};
}
另外,要將攔截器添加到請求鏈中,我們只需要將此bean添加到我們的@Configuration
類中即可,或者如我們先前所見,在屬性文件中對其進行聲明:
feign:
client:
config:
default:
requestInterceptors:
com.baeldung.cloud.openfeign.JSONPlaceHolderInterceptor
5.2。使用BasicAuthRequestInterceptor
另外,我們可以使用Spring Cloud OpenFeign提供的BasicAuthRequestInterceptor
類:
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("username", "password");
}
就這麼簡單!現在,所有請求都將包含基本身份驗證標頭。
6. Hystrix支持
Feign支持Hystrix,因此,如果啟用它,我們可以實現後備模式。
使用後備模式,當遠程服務調用失敗而不是生成異常時,服務使用者將執行備用代碼路徑,以嘗試通過其他方式執行操作。
為了實現該目標,我們需要啟用Hystrix,並在屬性文件中添加feign.hystrix.enabled=true
。
這使我們可以實現服務失敗時調用的後備方法:
@Component
public class JSONPlaceHolderFallback implements JSONPlaceHolderClient {
@Override
public List<Post> getPosts() {
return Collections.emptyList();
}
@Override
public Post getPostById(Long postId) {
return null;
}
}
為了讓Feign知道已經提供了fallback方法,我們還需要在@FeignClient
批註中設置我們的fallback類:
@FeignClient(value = "jplaceholder",
url = "https://jsonplaceholder.typicode.com/",
fallback = JSONPlaceHolderFallback.class)
public interface JSONPlaceHolderClient {
// APIs
}
7. 日誌
對於每個Feign客戶端,默認情況下都會創建一個記錄器。
要啟用日誌記錄,我們應該使用客戶端接口的包名稱在application.propertie
的文件中聲明它:
logging.level.com.baeldung.cloud.openfeign.client: DEBUG
或者,如果我們只想為包中的一個特定客戶端啟用日誌記錄,則可以使用完整的類名:
logging.level.com.baeldung.cloud.openfeign.client.JSONPlaceHolderClient: DEBUG
請注意,偽記錄僅響應DEBUG
級別。
我們可以為每個客戶端配置的Logger.Level
指示要記錄的數量:
@Configuration
public class ClientConfiguration {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.BASIC;
}
}
有四個日誌記錄級別可供選擇:
-
NONE
–不記錄,這是默認設置 -
BASIC
–僅記錄請求方法,URL和響應狀態 -
HEADERS
-記錄與請求和響應頭的基本信息一起 -
FULL
–記錄請求和響應的正文,標頭和元數據
8.錯誤處理
Feign的默認錯誤處理程序ErrorDecoder.default
始終拋出FeignException
。
現在,這種行為並不總是最有用的。因此,要自定義拋出的異常,我們可以使用CustomErrorDecoder
:
public class CustomErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
switch (response.status()){
case 400:
return new BadRequestException();
case 404:
return new NotFoundException();
default:
return new Exception("Generic error");
}
}
}
然後,就像我們之前所做的那樣,我們必須通過將一個bean添加到@Configuration
類來替換默認的ErrorDecoder
:
@Configuration
public class ClientConfiguration {
@Bean
public ErrorDecoder errorDecoder() {
return new CustomErrorDecoder();
}
}
9.結論
在本文中,我們討論了Spring Cloud OpenFeign及其在簡單示例應用程序中的實現。
此外,我們已經了解瞭如何配置客戶端,如何在請求中添加攔截器以及如何使用Hystrix
和ErrorDecoder.
處理錯誤ErrorDecoder.
像往常一樣,本教程中顯示的所有代碼示例均可在GitHub上獲得。