知識庫 / Spring / Spring Cloud RSS 訂閱

Spring Cloud OpenFeign 入門指南

Spring Cloud
HongKong
5
01:26 PM · Dec 06 ,2025

1. 概述

在本教程中,我們將描述 Spring Cloud OpenFeign——一個用於 Spring Boot 應用的聲明式 REST 客户端。

Feign 通過可插拔的註解支持(包括 Feign 註解和 JAX-RS 註解)使編寫 Web 服務客户端變得更容易。

此外,Spring Cloud 還支持使用 Spring MVC 註解以及與 Spring Web 中相同的 HttpMessageConverters

使用 Feign 的一個優點是,我們無需編寫任何代碼來調用服務,只需定義一個接口。

2. 依賴項

首先,我們將創建一個 Spring Boot Web 項目,並在我們的 pom.xml 文件中添加 spring-cloud-starter-openfeign 依賴項:

<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-openfeignspring-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:

  • 解碼器 – 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 = ClientConfiguration.class)
public class ClientConfiguration {

    @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-okhttpfeign-httpclient

4.2. 使用屬性進行配置

與其使用 Configuration 類,我們可以使用應用程序屬性來配置 Feign 客户端,如本 application.yaml 示例所示:

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

通過這種配置,我們將超時時間設置為五秒,並將每個已聲明的客户端的日誌級別設置為基本

最後,我們可以使用默認作為客户端名稱創建配置,以配置所有@FeignClient對象,或者可以聲明feign客户端名稱進行配置。

feign:
  client:
    config:
      jplaceholder:

如果同時存在 配置 Bean 和配置屬性,則配置屬性將覆蓋 配置 Bean 的值。

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,因此如果已啓用它,我們可以實現降級模式

通過降級模式,當遠程服務調用失敗時,而不是生成異常,服務消費者將執行備用代碼路徑,嘗試通過其他方式執行操作。

為了實現這一目標,我們需要通過在 properties 文件中添加 feign.hystrix.enabled=true 來啓用 Hystrix。

這允許我們實現在服務失敗時調用的降級方法:

@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</em/> 註解中設置我們的 fallback 類:

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

7. 日誌記錄

對於每個 Feign 客户端,默認情況下會創建一個日誌記錄器。

要啓用日誌記錄,我們應該在 application.properties 文件中使用客户端接口的包名進行聲明:

logging.level.com.baeldung.cloud.openfeign.client: DEBUG

或者,如果我們想僅為某個特定客户端啓用日誌記錄,可以使用完整的類名:

logging.level.com.baeldung.cloud.openfeign.client.JSONPlaceHolderClient: DEBUG

請注意,Feign 日誌僅響應 DEBUG 級別。

客户端可配置的 Logger.Level 指示日誌記錄的詳細程度:

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");
        }
    }
}

然後,正如我們之前所做的那樣,我們需要通過向 Configuration 類添加一個 Bean 來替換默認的 ErrorDecoder

public class ClientConfiguration {

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

9. 結論

在本文中,我們討論了 Spring Cloud OpenFeign 以及其在簡單示例應用程序中的實現。

我們還學習瞭如何配置客户端、為請求添加攔截器以及使用 HystrixErrorDecoder 處理錯誤。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.