Spring Cloud OpenFign簡介

原文

1. 概述

在本教程中,我們將描述 Spring Cloud OpenFeign一個用於Spring Boot應用程序的聲明性REST客戶端。
Feign使用可插入的註釋支持更輕鬆地編寫Web服務客戶端,其中包括Feign註釋和JAX-RS註釋。
此外,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和spring-cloud-dependencies。

3. 實現客戶端

接下來,我們需要將@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, 用於解碼響應
Encoder - SpringEncoder,用於編碼RequestBody
Logger - Slf4jLogger是Feign使用的默認記錄器
Contract - SpringMvcContract,提供註釋處理
Feign-Builder - 用於構造組件的HystrixFeign.Builder
Client - 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 -httpclient。

4.2 使用屬性配置

我們可以使用應用程序屬性來配置Feign客戶端,而不是使用@Configuration類,如此application.yml示例所示:

feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: basic

使用此配置,我們將應用程序中每個聲明的客戶端的超時設置爲5秒,並將記錄器級別設置爲基本。

最後,我們可以創建配置,使用default作爲客戶端名稱來配置所有@FeignClient 對象,或者我們可以爲配置聲明feign客戶端名稱:

feign:
  client:
    config:
      jplaceholder:

如果我們同時擁有@Configuration bean和配置屬性,配置屬性將覆蓋@Configuration值。

5. 攔截器

添加攔截器是Feign提供的另一個有用的功能。

對於每個HTTP請求/響應,攔截器可以執行各種隱式任務,從身份驗證到日誌記錄。

因此,在下面的代碼片段中,讓我們聲明一個請求攔截器,爲每個請求添加基本身份驗證:

@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

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知道已經提供了回退方法,我們還需要在@FeignClient註釋中設置我們的回退類:

@FeignClient(value = "jplaceholder",
  url = "https://jsonplaceholder.typicode.com/",
  fallback = JSONPlaceHolderFallback.class)
public interface JSONPlaceHolderClient {
    // APIs
}

7.記錄
對於每個Feign客戶端,默認情況下會創建一個記錄器。

要啓用日誌記錄,我們應該使用客戶端接口的包名稱在application.propertie文件中聲明它 :

1
logging.level.com.baeldung.cloud.openfeign.client: DEBUG
或者,如果我們只想爲包中的一個特定客戶端啓用日誌記錄,我們可以使用完整的類名:

1
logging.level.com.baeldung.cloud.openfeign.client.JSONPlaceHolderClient: DEBUG
請注意,Feign日誌記錄僅響應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。

現在,這種行爲並不總是最有用的。因此,要自定義拋出的Exception,我們可以使用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");
        }
    }
}

然後,正如我們之前所做的那樣,我們必須 通過向@Configuration類添加bean來 替換默認的ErrorDecoder:

@Configuration
public class ClientConfiguration {
 
    @Bean
    public ErrorDecoder errorDecoder() {
        return new CustomErrorDecoder();
    }
}

9. 結論

在本文中,我們在一個簡單的示例應用程序中討論了Spring Cloud OpenFeign及其實現。
此外,我們已經瞭解瞭如何配置客戶端,如何在我們的請求中添加攔截器,以及如何使用Hystrix和ErrorDecoder處理錯誤。
像往常一樣,本教程中顯示的所有代碼示例都可以 在GitHub上獲得。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章